// File: /workspace/github_c_makefile_star2_O1/genometools[P]genometools/src/external/sqlite-3.33.0/sqlite3.c
// Function: walTryBeginRead
static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
  volatile WalCkptInfo *pInfo;    /* Checkpoint information in wal-index */
  u32 mxReadMark;                 /* Largest aReadMark[] value */
  int mxI;                        /* Index of largest aReadMark[] value */
  int i;                          /* Loop counter */
  int rc = SQLITE_OK;             /* Return code  */
  u32 mxFrame;                    /* Wal frame to lock to */

  assert( pWal->readLock<0 );     /* Not currently locked */

  /* useWal may only be set for read/write connections */
  assert( (pWal->readOnly & WAL_SHM_RDONLY)==0 || useWal==0 );

  /* Take steps to avoid spinning forever if there is a protocol error.
  **
  ** Circumstances that cause a RETRY should only last for the briefest
  ** instances of time.  No I/O or other system calls are done while the
  ** locks are held, so the locks should not be held for very long. But
  ** if we are unlucky, another process that is holding a lock might get
  ** paged out or take a page-fault that is time-consuming to resolve,
  ** during the few nanoseconds that it is holding the lock.  In that case,
  ** it might take longer than normal for the lock to free.
  **
  ** After 5 RETRYs, we begin calling sqlite3OsSleep().  The first few
  ** calls to sqlite3OsSleep() have a delay of 1 microsecond.  Really this
  ** is more of a scheduler yield than an actual delay.  But on the 10th
  ** an subsequent retries, the delays start becoming longer and longer,
  ** so that on the 100th (and last) RETRY we delay for 323 milliseconds.
  ** The total delay time before giving up is less than 10 seconds.
  */
  if( cnt>5 ){
    int nDelay = 1;                      /* Pause time in microseconds */
    if( cnt>100 ){
      VVA_ONLY( pWal->lockError = 1; )
      return SQLITE_PROTOCOL;
    }
    if( cnt>=10 ) nDelay = (cnt-9)*(cnt-9)*39;
    sqlite3OsSleep(pWal->pVfs, nDelay);
  }

  if( !useWal ){
    assert( rc==SQLITE_OK );
    if( pWal->bShmUnreliable==0 ){
      rc = walIndexReadHdr(pWal, pChanged);
    }
    if( rc==SQLITE_BUSY ){
      /* If there is not a recovery running in another thread or process
      ** then convert BUSY errors to WAL_RETRY.  If recovery is known to
      ** be running, convert BUSY to BUSY_RECOVERY.  There is a race here
      ** which might cause WAL_RETRY to be returned even if BUSY_RECOVERY
      ** would be technically correct.  But the race is benign since with
      ** WAL_RETRY this routine will be called again and will probably be
      ** right on the second iteration.
      */
      if( pWal->apWiData[0]==0 ){
        /* This branch is taken when the xShmMap() method returns SQLITE_BUSY.
        ** We assume this is a transient condition, so return WAL_RETRY. The
        ** xShmMap() implementation used by the default unix and win32 VFS
        ** modules may return SQLITE_BUSY due to a race condition in the
        ** code that determines whether or not the shared-memory region
        ** must be zeroed before the requested page is returned.
        */
        rc = WAL_RETRY;
      }else if( SQLITE_OK==(rc = walLockShared(pWal, WAL_RECOVER_LOCK)) ){
        walUnlockShared(pWal, WAL_RECOVER_LOCK);
        rc = WAL_RETRY;
      }else if( rc==SQLITE_BUSY ){
        rc = SQLITE_BUSY_RECOVERY;
      }
    }
    if( rc!=SQLITE_OK ){
      return rc;
    }
    else if( pWal->bShmUnreliable ){
      return walBeginShmUnreliable(pWal, pChanged);
    }
  }

  assert( pWal->nWiData>0 );
  assert( pWal->apWiData[0]!=0 );
  pInfo = walCkptInfo(pWal);
  if( !useWal && AtomicLoad(&pInfo->nBackfill)==pWal->hdr.mxFrame
#ifdef SQLITE_ENABLE_SNAPSHOT
   && (pWal->pSnapshot==0 || pWal->hdr.mxFrame==0)
#endif
  ){
    /* The WAL has been completely backfilled (or it is empty).
    ** and can be safely ignored.
    */
    rc = walLockShared(pWal, WAL_READ_LOCK(0));
    walShmBarrier(pWal);
    if( rc==SQLITE_OK ){
      if( memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr)) ){
        /* It is not safe to allow the reader to continue here if frames
        ** may have been appended to the log before READ_LOCK(0) was obtained.
        ** When holding READ_LOCK(0), the reader ignores the entire log file,
        ** which implies that the database file contains a trustworthy
        ** snapshot. Since holding READ_LOCK(0) prevents a checkpoint from
        ** happening, this is usually correct.
        **
        ** However, if frames have been appended to the log (or if the log
        ** is wrapped and written for that matter) before the READ_LOCK(0)
        ** is obtained, that is not necessarily true. A checkpointer may
        ** have started to backfill the appended frames but crashed before
        ** it finished. Leaving a corrupt image in the database file.
        */
        walUnlockShared(pWal, WAL_READ_LOCK(0));
        return WAL_RETRY;
      }
      pWal->readLock = 0;
      return SQLITE_OK;
    }else if( rc!=SQLITE_BUSY ){
      return rc;
    }
  }

  /* If we get this far, it means that the reader will want to use
  ** the WAL to get at content from recent commits.  The job now is
  ** to select one of the aReadMark[] entries that is closest to
  ** but not exceeding pWal->hdr.mxFrame and lock that entry.
  */
  mxReadMark = 0;
  mxI = 0;
  mxFrame = pWal->hdr.mxFrame;
#ifdef SQLITE_ENABLE_SNAPSHOT
  if( pWal->pSnapshot && pWal->pSnapshot->mxFrame<mxFrame ){
    mxFrame = pWal->pSnapshot->mxFrame;
  }
#endif
  for(i=1; i<WAL_NREADER; i++){
    u32 thisMark = AtomicLoad(pInfo->aReadMark+i);
    if( mxReadMark<=thisMark && thisMark<=mxFrame ){
      assert( thisMark!=READMARK_NOT_USED );
      mxReadMark = thisMark;
      mxI = i;
    }
  }
  if( (pWal->readOnly & WAL_SHM_RDONLY)==0
   && (mxReadMark<mxFrame || mxI==0)
  ){
    for(i=1; i<WAL_NREADER; i++){
      rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1);
      if( rc==SQLITE_OK ){
        AtomicStore(pInfo->aReadMark+i,mxFrame);
        mxReadMark = mxFrame;
        mxI = i;
        walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
        break;
      }else if( rc!=SQLITE_BUSY ){
        return rc;
      }
    }
  }
  if( mxI==0 ){
    assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 );
    return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTINIT;
  }

  rc = walLockShared(pWal, WAL_READ_LOCK(mxI));
  if( rc ){
    return rc==SQLITE_BUSY ? WAL_RETRY : rc;
  }
  /* Now that the read-lock has been obtained, check that neither the
  ** value in the aReadMark[] array or the contents of the wal-index
  ** header have changed.
  **
  ** It is necessary to check that the wal-index header did not change
  ** between the time it was read and when the shared-lock was obtained
  ** on WAL_READ_LOCK(mxI) was obtained to account for the possibility
  ** that the log file may have been wrapped by a writer, or that frames
  ** that occur later in the log than pWal->hdr.mxFrame may have been
  ** copied into the database by a checkpointer. If either of these things
  ** happened, then reading the database with the current value of
  ** pWal->hdr.mxFrame risks reading a corrupted snapshot. So, retry
  ** instead.
  **
  ** Before checking that the live wal-index header has not changed
  ** since it was read, set Wal.minFrame to the first frame in the wal
  ** file that has not yet been checkpointed. This client will not need
  ** to read any frames earlier than minFrame from the wal file - they
  ** can be safely read directly from the database file.
  **
  ** Because a ShmBarrier() call is made between taking the copy of
  ** nBackfill and checking that the wal-header in shared-memory still
  ** matches the one cached in pWal->hdr, it is guaranteed that the
  ** checkpointer that set nBackfill was not working with a wal-index
  ** header newer than that cached in pWal->hdr. If it were, that could
  ** cause a problem. The checkpointer could omit to checkpoint
  ** a version of page X that lies before pWal->minFrame (call that version
  ** A) on the basis that there is a newer version (version B) of the same
  ** page later in the wal file. But if version B happens to like past
  ** frame pWal->hdr.mxFrame - then the client would incorrectly assume
  ** that it can read version A from the database file. However, since
  ** we can guarantee that the checkpointer that set nBackfill could not
  ** see any pages past pWal->hdr.mxFrame, this problem does not come up.
  */
  pWal->minFrame = AtomicLoad(&pInfo->nBackfill)+1;
  walShmBarrier(pWal);
  if( AtomicLoad(pInfo->aReadMark+mxI)!=mxReadMark
   || memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr))
  ){
    walUnlockShared(pWal, WAL_READ_LOCK(mxI));
    return WAL_RETRY;
  }else{
    assert( mxReadMark<=pWal->hdr.mxFrame );
    pWal->readLock = (i16)mxI;
  }
  return rc;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movl %edx, %ebp
movq %rsi, %r15
movq %rdi, %r8
cmpl $0x6, %ecx
movq %rdi, 0x8(%rsp)
jl 0x2913b8
movl $0xf, %edi
cmpl $0x64, %ecx
jg 0x2916c2
leal -0x9(%rcx), %eax
imull %eax, %eax
imull $0x27, %eax, %eax
cmpl $0xa, %ecx
movl $0x1, %esi
cmovgel %eax, %esi
movq (%r8), %rdi
callq *0x70(%rdi)
movq 0x8(%rsp), %r8
testl %ebp, %ebp
je 0x291554
xorl %ebx, %ebx
movq 0x30(%r8), %rax
movq (%rax), %r12
movl $0x0, %edi
testl %ebp, %ebp
jne 0x29147c
movl 0x60(%r12), %eax
movl $0x0, %edi
cmpl 0x58(%r8), %eax
jne 0x29147c
xorl %edi, %edi
cmpb $0x0, 0x3f(%r8)
jne 0x291413
movq 0x8(%r8), %rdi
movq (%rdi), %rax
movl $0x3, %esi
movl $0x1, %edx
movl $0x6, %ecx
callq *0x70(%rax)
movq 0x8(%rsp), %r8
movl %eax, %edi
cmpb $0x2, 0x3f(%r8)
je 0x29142f
movq %rdi, %r14
movq 0x8(%r8), %rdi
movq (%rdi), %rax
callq *0x78(%rax)
movq %r14, %rdi
movq 0x8(%rsp), %r8
cmpl $0x5, %edi
je 0x29147c
testl %edi, %edi
jne 0x2916c2
leaq 0x48(%r8), %rsi
movq 0x30(%r8), %rax
movq (%rax), %rdi
movl $0x30, %edx
movq %r8, %rbx
callq 0x17830
testl %eax, %eax
je 0x2917ea
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
cmpb $0x0, 0x3f(%rbx)
jne 0x2916c2
movq 0x8(%rbx), %rdi
movq (%rdi), %rax
movl $0x3, %esi
jmp 0x29164c
movl 0x58(%r8), %r13d
xorl %eax, %eax
xorl %r14d, %r14d
movl 0x68(%r12,%rax,4), %ecx
cmpl %ecx, %ebx
seta %dl
cmpl %r13d, %ecx
seta %sil
orb %dl, %sil
incq %rax
testb %sil, %sil
jne 0x2914a6
movl %eax, %r14d
movl %ecx, %ebx
cmpq $0x4, %rax
jne 0x291485
testb $0x2, 0x42(%r8)
jne 0x291503
cmpl %r13d, %ebx
jb 0x2914bd
testl %r14d, %r14d
jne 0x291503
xorl %ebp, %ebp
leaq 0x4(%rbp), %r15
cmpb $0x0, 0x3f(%r8)
movl $0x0, %edi
jne 0x2914ed
movq 0x8(%r8), %rdi
movq (%rdi), %rax
movl %r15d, %esi
movl $0x1, %edx
movl $0xa, %ecx
callq *0x70(%rax)
movq 0x8(%rsp), %r8
movl %eax, %edi
cmpl $0x5, %edi
jne 0x291660
incq %rbp
cmpl $0x4, %ebp
jne 0x2914bf
movl $0x5, %edi
movl %ebx, %r13d
testl %r14d, %r14d
je 0x2915cf
leal 0x3(%r14), %r15d
xorl %eax, %eax
movq 0x8(%rsp), %rcx
cmpb $0x0, 0x3f(%rcx)
jne 0x29153c
movq 0x8(%rcx), %rdi
movq (%rdi), %rax
movl %r15d, %esi
movl $0x1, %edx
movl $0x6, %ecx
callq *0x70(%rax)
movq 0x8(%rsp), %rcx
testl %eax, %eax
je 0x2915e5
cmpl $0x5, %eax
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
cmovnel %eax, %edi
jmp 0x2916c2
xorl %edi, %edi
cmpb $0x0, 0x46(%r8)
jne 0x29156f
movq %r8, %rdi
movq %r15, %rsi
callq 0x291964
movq 0x8(%rsp), %r8
movl %eax, %edi
cmpl $0x5, %edi
jne 0x2916be
movq 0x30(%r8), %rax
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
cmpq $0x0, (%rax)
je 0x2916be
xorl %eax, %eax
cmpb $0x0, 0x3f(%r8)
jne 0x2915b7
movq 0x8(%r8), %rdi
movq (%rdi), %rax
movl $0x2, %esi
movl $0x1, %edx
movl $0x6, %ecx
callq *0x70(%rax)
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
movq 0x8(%rsp), %r8
testl %eax, %eax
je 0x291694
cmpl $0x5, %eax
movl $0x105, %edi            # imm = 0x105
cmovnel %eax, %edi
jmp 0x2916be
xorl %eax, %eax
cmpl $0x5, %edi
sete %al
negl %eax
orl $0x508, %eax            # imm = 0x508
movl %eax, %edi
jmp 0x2916c2
movl 0x60(%r12), %eax
incl %eax
movl %eax, 0x78(%rcx)
cmpb $0x2, 0x3f(%rcx)
je 0x291604
movq 0x8(%rcx), %rdi
movq (%rdi), %rax
callq *0x78(%rax)
movq 0x8(%rsp), %rcx
movslq %r14d, %rax
movl 0x64(%r12,%rax,4), %eax
cmpl %r13d, %eax
jne 0x291633
leaq 0x48(%rcx), %rsi
movq 0x30(%rcx), %rax
movq (%rax), %rdi
movl $0x30, %edx
callq 0x17830
movq 0x8(%rsp), %rcx
testl %eax, %eax
je 0x291770
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
cmpb $0x0, 0x3f(%rcx)
jne 0x2916c2
movq 0x8(%rcx), %rdi
movq (%rdi), %rax
movl %r15d, %esi
movl $0x1, %edx
movl $0x5, %ecx
callq *0x70(%rax)
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
jmp 0x2916c2
testl %edi, %edi
jne 0x2916c2
movl %r13d, 0x68(%r12,%rbp,4)
incq %rbp
cmpb $0x0, 0x3f(%r8)
jne 0x29168a
movq 0x8(%r8), %rdi
movq (%rdi), %rax
movl %r15d, %esi
movl $0x1, %edx
movl $0x9, %ecx
callq *0x70(%rax)
xorl %edi, %edi
movl %ebp, %r14d
jmp 0x291506
cmpb $0x0, 0x3f(%r8)
jne 0x2916be
movq 0x8(%r8), %rdi
movq (%rdi), %rax
movl $0x2, %esi
movl $0x1, %edx
movl $0x5, %ecx
callq *0x70(%rax)
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
movq 0x8(%rsp), %r8
testl %edi, %edi
je 0x2916d3
movl %edi, %eax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpb $0x0, 0x46(%r8)
je 0x2913c0
xorl %eax, %eax
cmpb $0x0, 0x3f(%r8)
jne 0x291705
movq 0x8(%r8), %rdi
movq (%rdi), %rax
movl $0x3, %esi
movl $0x1, %edx
movl $0x6, %ecx
callq *0x70(%rax)
movq 0x8(%rsp), %r8
testl %eax, %eax
je 0x29170e
cmpl $0x5, %eax
jmp 0x29177a
movw $0x0, 0x3c(%r8)
movq 0x8(%r8), %rdi
movq (%rdi), %rax
movq %r8, %rbx
leaq 0x38(%rsp), %r8
xorl %esi, %esi
movl $0x8000, %edx           # imm = 0x8000
xorl %ecx, %ecx
callq *0x68(%rax)
cmpl $0x508, %eax            # imm = 0x508
jne 0x291777
movq 0x10(%rbx), %rdi
movq 0x30(%rbx), %rax
movq (%rax), %rax
movups (%rax), %xmm0
movups 0x10(%rax), %xmm1
movups 0x20(%rax), %xmm2
movups %xmm0, 0x48(%rbx)
movups %xmm1, 0x58(%rbx)
movups %xmm2, 0x68(%rbx)
movq (%rdi), %rax
leaq 0x10(%rsp), %rsi
callq *0x30(%rax)
testl %eax, %eax
je 0x2917f7
movl %eax, %edx
jmp 0x291782
movw %r14w, 0x3c(%rcx)
jmp 0x2917f0
cmpl $0x8, %eax
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
cmovnel %eax, %edx
xorl %r12d, %r12d
movq %rdx, %r14
movq %r12, %rdi
callq 0x27c490
movq %r14, %rdi
testl %edi, %edi
je 0x2916c2
movq 0x8(%rsp), %rdi
cmpl $0x0, 0x28(%rdi)
jle 0x2917d2
xorl %ebx, %ebx
movq 0x30(%rdi), %rax
movq (%rax,%rbx,8), %rdi
callq 0x27c490
movq 0x8(%rsp), %rdi
movq 0x30(%rdi), %rax
movq $0x0, (%rax,%rbx,8)
incq %rbx
movslq 0x28(%rdi), %rax
cmpq %rax, %rbx
jl 0x2917a8
movb $0x0, 0x46(%rdi)
callq 0x2925b7
movl $0x1, (%r15)
movq %r14, %rdi
jmp 0x2916c2
movw $0x0, 0x3c(%rbx)
xorl %edi, %edi
jmp 0x2916c2
cmpq $0x1f, 0x10(%rsp)
jg 0x29181e
movl $0x1, (%r15)
xorl %r12d, %r12d
movq 0x8(%rsp), %rax
cmpl 0x58(%rax), %r12d
movl $0x0, %edx
sbbl %edx, %edx
jmp 0x291785
movq 0x8(%rsp), %rax
movq 0x10(%rax), %rdi
movq (%rdi), %rax
xorl %r12d, %r12d
leaq 0x40(%rsp), %rsi
movl $0x20, %edx
xorl %ecx, %ecx
callq *0x10(%rax)
movl %eax, %edx
testl %eax, %eax
jne 0x291785
movq 0x8(%rsp), %rcx
movq 0x68(%rcx), %rax
cmpq 0x50(%rsp), %rax
je 0x291863
xorl %r12d, %r12d
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
jmp 0x291785
movzwl 0x56(%rcx), %ebx
leaq 0x18(%rbx), %r13
callq 0x27bed9
testl %eax, %eax
je 0x291879
xorl %r12d, %r12d
jmp 0x291884
movq %r13, %rdi
callq 0x27c381
movq %rax, %r12
xorl %edx, %edx
testq %r12, %r12
je 0x29195a
movq 0x8(%rsp), %r14
movl 0x58(%r14), %eax
movl 0x60(%r14), %ecx
movl %ecx, 0x20(%rsp)
movl 0x64(%r14), %ecx
movl %ecx, 0x1c(%rsp)
movzwl 0x56(%r14), %ebp
addq $0x18, %rbp
imulq %rax, %rbp
leaq 0x20(,%r13), %rax
addq %rbp, %rax
cmpq 0x10(%rsp), %rax
jg 0x291945
leaq 0x18(%r12), %rax
movq %rax, 0x28(%rsp)
addq $0x20, %rbp
movq 0x10(%r14), %rdi
movq (%rdi), %rax
movq %r12, %rsi
movl %r13d, %edx
movq %rbp, %rcx
callq *0x10(%rax)
testl %eax, %eax
je 0x2918f2
xorl %ecx, %ecx
movl %eax, %edx
jmp 0x29192f
movq %r14, %rdi
leaq 0x34(%rsp), %rsi
leaq 0x24(%rsp), %rdx
movq 0x28(%rsp), %rcx
movq %r12, %r8
callq 0x2924fa
testl %eax, %eax
je 0x291926
xorl %edx, %edx
cmpl $0x0, 0x24(%rsp)
sete %cl
setne %dl
negl %edx
movq 0x8(%rsp), %r14
jmp 0x29192f
xorl %ecx, %ecx
movq 0x8(%rsp), %r14
xorl %edx, %edx
testb %cl, %cl
je 0x291945
addq %r13, %rbp
leaq (%rbx,%rbp), %rax
addq $0x18, %rax
cmpq 0x10(%rsp), %rax
jle 0x2918d5
movl 0x20(%rsp), %eax
movl %eax, 0x60(%r14)
movl 0x1c(%rsp), %eax
movl %eax, 0x64(%r14)
jmp 0x291785
movl $0x7, %edx
jmp 0x291782