// File: /workspace/github_c_makefile_star2_O0/genometools[P]genometools/src/external/sqlite-3.33.0/sqlite3.c
// Function: walCheckpoint
static int walCheckpoint(
  Wal *pWal,                      /* Wal connection */
  sqlite3 *db,                    /* Check for interrupts on this handle */
  int eMode,                      /* One of PASSIVE, FULL or RESTART */
  int (*xBusy)(void*),            /* Function to call when busy */
  void *pBusyArg,                 /* Context argument for xBusyHandler */
  int sync_flags,                 /* Flags for OsSync() (or 0) */
  u8 *zBuf                        /* Temporary buffer to use */
){
  int rc = SQLITE_OK;             /* Return code */
  int szPage;                     /* Database page-size */
  WalIterator *pIter = 0;         /* Wal iterator context */
  u32 iDbpage = 0;                /* Next database page to write */
  u32 iFrame = 0;                 /* Wal frame containing data for iDbpage */
  u32 mxSafeFrame;                /* Max frame that can be backfilled */
  u32 mxPage;                     /* Max database page to write */
  int i;                          /* Loop counter */
  volatile WalCkptInfo *pInfo;    /* The checkpoint status information */

  szPage = walPagesize(pWal);
  testcase( szPage<=32768 );
  testcase( szPage>=65536 );
  pInfo = walCkptInfo(pWal);
  if( pInfo->nBackfill<pWal->hdr.mxFrame ){

    /* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
    ** in the SQLITE_CHECKPOINT_PASSIVE mode. */
    assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );

    /* Compute in mxSafeFrame the index of the last frame of the WAL that is
    ** safe to write into the database.  Frames beyond mxSafeFrame might
    ** overwrite database pages that are in use by active readers and thus
    ** cannot be backfilled from the WAL.
    */
    mxSafeFrame = pWal->hdr.mxFrame;
    mxPage = pWal->hdr.nPage;
    for(i=1; i<WAL_NREADER; i++){
      u32 y = AtomicLoad(pInfo->aReadMark+i);
      if( mxSafeFrame>y ){
        assert( y<=pWal->hdr.mxFrame );
        rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1);
        if( rc==SQLITE_OK ){
          u32 iMark = (i==1 ? mxSafeFrame : READMARK_NOT_USED);
          AtomicStore(pInfo->aReadMark+i, iMark);
          walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
        }else if( rc==SQLITE_BUSY ){
          mxSafeFrame = y;
          xBusy = 0;
        }else{
          goto walcheckpoint_out;
        }
      }
    }

    /* Allocate the iterator */
    if( pInfo->nBackfill<mxSafeFrame ){
      rc = walIteratorInit(pWal, pInfo->nBackfill, &pIter);
      assert( rc==SQLITE_OK || pIter==0 );
    }

    if( pIter
     && (rc = walBusyLock(pWal,xBusy,pBusyArg,WAL_READ_LOCK(0),1))==SQLITE_OK
    ){
      u32 nBackfill = pInfo->nBackfill;

      pInfo->nBackfillAttempted = mxSafeFrame;

      /* Sync the WAL to disk */
      rc = sqlite3OsSync(pWal->pWalFd, CKPT_SYNC_FLAGS(sync_flags));

      /* If the database may grow as a result of this checkpoint, hint
      ** about the eventual size of the db file to the VFS layer.
      */
      if( rc==SQLITE_OK ){
        i64 nReq = ((i64)mxPage * szPage);
        i64 nSize;                    /* Current size of database file */
        sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_START, 0);
        rc = sqlite3OsFileSize(pWal->pDbFd, &nSize);
        if( rc==SQLITE_OK && nSize<nReq ){
          if( (nSize+65536+(i64)pWal->hdr.mxFrame*szPage)<nReq ){
            /* If the size of the final database is larger than the current
            ** database plus the amount of data in the wal file, plus the
            ** maximum size of the pending-byte page (65536 bytes), then
            ** must be corruption somewhere.  */
            rc = SQLITE_CORRUPT_BKPT;
          }else{
            sqlite3OsFileControlHint(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT,&nReq);
          }
        }

      }

      /* Iterate through the contents of the WAL, copying data to the db file */
      while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){
        i64 iOffset;
        assert( walFramePgno(pWal, iFrame)==iDbpage );
        if( AtomicLoad(&db->u1.isInterrupted) ){
          rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT;
          break;
        }
        if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ){
          continue;
        }
        iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE;
        /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */
        rc = sqlite3OsRead(pWal->pWalFd, zBuf, szPage, iOffset);
        if( rc!=SQLITE_OK ) break;
        iOffset = (iDbpage-1)*(i64)szPage;
        testcase( IS_BIG_INT(iOffset) );
        rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset);
        if( rc!=SQLITE_OK ) break;
      }
      sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_DONE, 0);

      /* If work was actually accomplished... */
      if( rc==SQLITE_OK ){
        if( mxSafeFrame==walIndexHdr(pWal)->mxFrame ){
          i64 szDb = pWal->hdr.nPage*(i64)szPage;
          testcase( IS_BIG_INT(szDb) );
          rc = sqlite3OsTruncate(pWal->pDbFd, szDb);
          if( rc==SQLITE_OK ){
            rc = sqlite3OsSync(pWal->pDbFd, CKPT_SYNC_FLAGS(sync_flags));
          }
        }
        if( rc==SQLITE_OK ){
          AtomicStore(&pInfo->nBackfill, mxSafeFrame);
        }
      }

      /* Release the reader lock held while backfilling */
      walUnlockExclusive(pWal, WAL_READ_LOCK(0), 1);
    }

    if( rc==SQLITE_BUSY ){
      /* Reset the return code so as not to report a checkpoint failure
      ** just because there are active readers.  */
      rc = SQLITE_OK;
    }
  }

  /* If this is an SQLITE_CHECKPOINT_RESTART or TRUNCATE operation, and the
  ** entire wal file has been copied into the database file, then block
  ** until all readers have finished using the wal file. This ensures that
  ** the next process to write to the database restarts the wal file.
  */
  if( rc==SQLITE_OK && eMode!=SQLITE_CHECKPOINT_PASSIVE ){
    assert( pWal->writeLock );
    if( pInfo->nBackfill<pWal->hdr.mxFrame ){
      rc = SQLITE_BUSY;
    }else if( eMode>=SQLITE_CHECKPOINT_RESTART ){
      u32 salt1;
      sqlite3_randomness(4, &salt1);
      assert( pInfo->nBackfill==pWal->hdr.mxFrame );
      rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(1), WAL_NREADER-1);
      if( rc==SQLITE_OK ){
        if( eMode==SQLITE_CHECKPOINT_TRUNCATE ){
          /* IMPLEMENTATION-OF: R-44699-57140 This mode works the same way as
          ** SQLITE_CHECKPOINT_RESTART with the addition that it also
          ** truncates the log file to zero bytes just prior to a
          ** successful return.
          **
          ** In theory, it might be safe to do this without updating the
          ** wal-index header in shared memory, as all subsequent reader or
          ** writer clients should see that the entire log file has been
          ** checkpointed and behave accordingly. This seems unsafe though,
          ** as it would leave the system in a state where the contents of
          ** the wal-index header do not match the contents of the
          ** file-system. To avoid this, update the wal-index header to
          ** indicate that the log file contains zero valid frames.  */
          walRestartHdr(pWal, salt1);
          rc = sqlite3OsTruncate(pWal->pWalFd, 0);
        }
        walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
      }
    }
  }

 walcheckpoint_out:
  walIteratorFree(pIter);
  return rc;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xc0, %rsp
movq 0x10(%rbp), %rax
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movl %r9d, -0x2c(%rbp)
movl $0x0, -0x30(%rbp)
movq $0x0, -0x40(%rbp)
movl $0x0, -0x44(%rbp)
movl $0x0, -0x48(%rbp)
movq -0x8(%rbp), %rdi
callq 0x3e56c0
movl %eax, -0x34(%rbp)
movq -0x8(%rbp), %rdi
callq 0x3de5c0
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rax
movl (%rax), %eax
movq -0x8(%rbp), %rcx
cmpl 0x58(%rcx), %eax
jae 0x3e5b63
movq -0x8(%rbp), %rax
movl 0x58(%rax), %eax
movl %eax, -0x4c(%rbp)
movq -0x8(%rbp), %rax
movl 0x5c(%rax), %eax
movl %eax, -0x50(%rbp)
movl $0x1, -0x54(%rbp)
cmpl $0x5, -0x54(%rbp)
jge 0x3e584c
movq -0x60(%rbp), %rax
movslq -0x54(%rbp), %rcx
movl 0x4(%rax,%rcx,4), %eax
movl %eax, -0x68(%rbp)
movl -0x68(%rbp), %eax
movl %eax, -0x64(%rbp)
movl -0x4c(%rbp), %eax
cmpl -0x64(%rbp), %eax
jbe 0x3e583c
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
movl -0x54(%rbp), %ecx
addl $0x3, %ecx
movl $0x1, %r8d
callq 0x3e5650
movl %eax, -0x30(%rbp)
cmpl $0x0, -0x30(%rbp)
jne 0x3e581d
cmpl $0x1, -0x54(%rbp)
jne 0x3e57dc
movl -0x4c(%rbp), %eax
movl %eax, -0xac(%rbp)
jmp 0x3e57e9
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movl %eax, -0xac(%rbp)
jmp 0x3e57e9
movl -0xac(%rbp), %eax
movl %eax, -0x6c(%rbp)
movq -0x60(%rbp), %rax
movslq -0x54(%rbp), %rcx
movl -0x6c(%rbp), %edx
movl %edx, -0x70(%rbp)
movl -0x70(%rbp), %edx
movl %edx, 0x4(%rax,%rcx,4)
movq -0x8(%rbp), %rdi
movl -0x54(%rbp), %esi
addl $0x3, %esi
movl $0x1, %edx
callq 0x3de700
jmp 0x3e583a
cmpl $0x5, -0x30(%rbp)
jne 0x3e5833
movl -0x64(%rbp), %eax
movl %eax, -0x4c(%rbp)
movq $0x0, -0x20(%rbp)
jmp 0x3e5838
jmp 0x3e5c0a
jmp 0x3e583a
jmp 0x3e583c
jmp 0x3e583e
movl -0x54(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x54(%rbp)
jmp 0x3e577a
movq -0x60(%rbp), %rax
movl (%rax), %eax
cmpl -0x4c(%rbp), %eax
jae 0x3e586d
movq -0x8(%rbp), %rdi
movq -0x60(%rbp), %rax
movl (%rax), %esi
leaq -0x40(%rbp), %rdx
callq 0x3e5c20
movl %eax, -0x30(%rbp)
cmpq $0x0, -0x40(%rbp)
je 0x3e5b54
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
movl $0x3, %ecx
movl $0x1, %r8d
callq 0x3e5650
movl %eax, -0x30(%rbp)
cmpl $0x0, %eax
jne 0x3e5b54
movq -0x60(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x74(%rbp)
movl -0x4c(%rbp), %ecx
movq -0x60(%rbp), %rax
movl %ecx, 0x20(%rax)
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rdi
movl -0x2c(%rbp), %esi
sarl $0x2, %esi
andl $0x3, %esi
callq 0x3ddf70
movl %eax, -0x30(%rbp)
cmpl $0x0, -0x30(%rbp)
jne 0x3e5973
movl -0x50(%rbp), %eax
movslq -0x34(%rbp), %rcx
imulq %rcx, %rax
movq %rax, -0x80(%rbp)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
movl $0x27, %esi
xorl %eax, %eax
movl %eax, %edx
callq 0x3d4130
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
leaq -0x88(%rbp), %rsi
callq 0x3dfbd0
movl %eax, -0x30(%rbp)
cmpl $0x0, -0x30(%rbp)
jne 0x3e5971
movq -0x88(%rbp), %rax
cmpq -0x80(%rbp), %rax
jge 0x3e5971
movq -0x88(%rbp), %rax
addq $0x10000, %rax          # imm = 0x10000
movq -0x8(%rbp), %rcx
movl 0x58(%rcx), %ecx
movslq -0x34(%rbp), %rdx
imulq %rdx, %rcx
addq %rcx, %rax
cmpq -0x80(%rbp), %rax
jge 0x3e5959
movl $0xefec, %edi           # imm = 0xEFEC
callq 0x3dff80
movl %eax, -0x30(%rbp)
jmp 0x3e596f
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
movl $0x5, %esi
leaq -0x80(%rbp), %rdx
callq 0x3dbb10
jmp 0x3e5971
jmp 0x3e5973
jmp 0x3e5975
xorl %eax, %eax
cmpl $0x0, -0x30(%rbp)
movb %al, -0xad(%rbp)
jne 0x3e59a3
movq -0x40(%rbp), %rdi
leaq -0x44(%rbp), %rsi
leaq -0x48(%rbp), %rdx
callq 0x3e5e90
movl %eax, %ecx
xorl %eax, %eax
cmpl %ecx, %eax
sete %al
movb %al, -0xad(%rbp)
movb -0xad(%rbp), %al
testb $0x1, %al
jne 0x3e59b2
jmp 0x3e5a94
movq -0x10(%rbp), %rax
movl 0x168(%rax), %eax
movl %eax, -0x94(%rbp)
cmpl $0x0, -0x94(%rbp)
je 0x3e59eb
movq -0x10(%rbp), %rax
movzbl 0x61(%rax), %edx
movl $0x9, %eax
movl $0x7, %ecx
cmpl $0x0, %edx
cmovnel %ecx, %eax
movl %eax, -0x30(%rbp)
jmp 0x3e5a94
movl -0x48(%rbp), %eax
cmpl -0x74(%rbp), %eax
jbe 0x3e5a03
movl -0x48(%rbp), %eax
cmpl -0x4c(%rbp), %eax
ja 0x3e5a03
movl -0x44(%rbp), %eax
cmpl -0x50(%rbp), %eax
jbe 0x3e5a08
jmp 0x3e5975
movl -0x48(%rbp), %eax
subl $0x1, %eax
movl %eax, %eax
movl -0x34(%rbp), %ecx
addl $0x18, %ecx
movslq %ecx, %rcx
imulq %rcx, %rax
addq $0x20, %rax
addq $0x18, %rax
movq %rax, -0x90(%rbp)
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rdi
movq 0x10(%rbp), %rsi
movl -0x34(%rbp), %edx
movq -0x90(%rbp), %rcx
callq 0x3dfc00
movl %eax, -0x30(%rbp)
cmpl $0x0, -0x30(%rbp)
je 0x3e5a52
jmp 0x3e5a94
movl -0x44(%rbp), %eax
subl $0x1, %eax
movl %eax, %eax
movslq -0x34(%rbp), %rcx
imulq %rcx, %rax
movq %rax, -0x90(%rbp)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
movq 0x10(%rbp), %rsi
movl -0x34(%rbp), %edx
movq -0x90(%rbp), %rcx
callq 0x3c6930
movl %eax, -0x30(%rbp)
cmpl $0x0, -0x30(%rbp)
je 0x3e5a8f
jmp 0x3e5a94
jmp 0x3e5975
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
movl $0x25, %esi
xorl %eax, %eax
movl %eax, %edx
callq 0x3d4130
cmpl $0x0, -0x30(%rbp)
jne 0x3e5b41
movl -0x4c(%rbp), %eax
movl %eax, -0xb4(%rbp)
movq -0x8(%rbp), %rdi
callq 0x3ddcf0
movq %rax, %rcx
movl -0xb4(%rbp), %eax
movl 0x10(%rcx), %ecx
cmpl %ecx, %eax
jne 0x3e5b24
movq -0x8(%rbp), %rax
movl 0x5c(%rax), %eax
movslq -0x34(%rbp), %rcx
imulq %rcx, %rax
movq %rax, -0xa0(%rbp)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0xa0(%rbp), %rsi
callq 0x3e01f0
movl %eax, -0x30(%rbp)
cmpl $0x0, -0x30(%rbp)
jne 0x3e5b22
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
movl -0x2c(%rbp), %esi
sarl $0x2, %esi
andl $0x3, %esi
callq 0x3ddf70
movl %eax, -0x30(%rbp)
jmp 0x3e5b24
cmpl $0x0, -0x30(%rbp)
jne 0x3e5b3f
movq -0x60(%rbp), %rax
movl -0x4c(%rbp), %ecx
movl %ecx, -0xa4(%rbp)
movl -0xa4(%rbp), %ecx
movl %ecx, (%rax)
jmp 0x3e5b41
movq -0x8(%rbp), %rdi
movl $0x3, %esi
movl $0x1, %edx
callq 0x3de700
cmpl $0x5, -0x30(%rbp)
jne 0x3e5b61
movl $0x0, -0x30(%rbp)
jmp 0x3e5b63
cmpl $0x0, -0x30(%rbp)
jne 0x3e5c08
cmpl $0x0, -0x14(%rbp)
je 0x3e5c08
movq -0x60(%rbp), %rax
movl (%rax), %eax
movq -0x8(%rbp), %rcx
cmpl 0x58(%rcx), %eax
jae 0x3e5b8f
movl $0x5, -0x30(%rbp)
jmp 0x3e5c06
cmpl $0x2, -0x14(%rbp)
jl 0x3e5c04
movl $0x4, %edi
leaq -0xa8(%rbp), %rsi
callq 0x3c3b60
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
movl $0x4, %r8d
movl %r8d, %ecx
callq 0x3e5650
movl %eax, -0x30(%rbp)
cmpl $0x0, -0x30(%rbp)
jne 0x3e5c02
cmpl $0x3, -0x14(%rbp)
jne 0x3e5bf2
movq -0x8(%rbp), %rdi
movl -0xa8(%rbp), %esi
callq 0x3de630
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x3e01f0
movl %eax, -0x30(%rbp)
movq -0x8(%rbp), %rdi
movl $0x4, %edx
movl %edx, %esi
callq 0x3de700
jmp 0x3e5c04
jmp 0x3e5c06
jmp 0x3e5c08
jmp 0x3e5c0a
movq -0x40(%rbp), %rdi
callq 0x3e5f90
movl -0x30(%rbp), %eax
addq $0xc0, %rsp
popq %rbp
retq
nop