// File: /workspace/github_c_makefile_star2_O0/shifengbin[P]bishe/Output/../Persistence/sqlite3.c
// Function: walCheckpoint
static int walCheckpoint(
  Wal *pWal,                      /* Wal connection */
  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 ){

    /* Allocate the iterator */
    rc = walIteratorInit(pWal, &pIter);
    if( rc!=SQLITE_OK ){
      return rc;
    }
    assert( pIter );

    /* 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++){
      /* Thread-sanitizer reports that the following is an unsafe read,
      ** as some other thread may be in the process of updating the value
      ** of the aReadMark[] slot. The assumption here is that if that is
      ** happening, the other client may only be increasing the value,
      ** not decreasing it. So assuming either that either the "old" or
      ** "new" version of the value is read, and not some arbitrary value
      ** that would never be written by a real client, things are still 
      ** safe.  */
      u32 y = 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 ){
          pInfo->aReadMark[i] = (i==1 ? mxSafeFrame : READMARK_NOT_USED);
          walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
        }else if( rc==SQLITE_BUSY ){
          mxSafeFrame = y;
          xBusy = 0;
        }else{
          goto walcheckpoint_out;
        }
      }
    }

    if( pInfo->nBackfill<mxSafeFrame
     && (rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(0),1))==SQLITE_OK
    ){
      i64 nSize;                    /* Current size of database file */
      u32 nBackfill = pInfo->nBackfill;

      pInfo->nBackfillAttempted = mxSafeFrame;

      /* Sync the WAL to disk */
      if( sync_flags ){
        rc = sqlite3OsSync(pWal->pWalFd, 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);
        rc = sqlite3OsFileSize(pWal->pDbFd, &nSize);
        if( rc==SQLITE_OK && nSize<nReq ){
          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( 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;
      }

      /* 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 && sync_flags ){
            rc = sqlite3OsSync(pWal->pDbFd, sync_flags);
          }
        }
        if( rc==SQLITE_OK ){
          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 $0xb0, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movl %r8d, -0x2c(%rbp)
movq %r9, -0x38(%rbp)
movl $0x0, -0x3c(%rbp)
movq $0x0, -0x48(%rbp)
movl $0x0, -0x4c(%rbp)
movl $0x0, -0x50(%rbp)
movq -0x10(%rbp), %rdi
callq 0x2ca10
movl %eax, -0x40(%rbp)
movq -0x10(%rbp), %rdi
callq 0x29150
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rax
movl (%rax), %eax
movq -0x10(%rbp), %rcx
cmpl 0x58(%rcx), %eax
jae 0x2cdf6
movq -0x10(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x2cf00
movl %eax, -0x3c(%rbp)
cmpl $0x0, -0x3c(%rbp)
je 0x2cacc
movl -0x3c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x2ceac
movq -0x10(%rbp), %rax
movl 0x58(%rax), %eax
movl %eax, -0x54(%rbp)
movq -0x10(%rbp), %rax
movl 0x5c(%rax), %eax
movl %eax, -0x58(%rbp)
movl $0x1, -0x5c(%rbp)
cmpl $0x5, -0x5c(%rbp)
jge 0x2cba7
movq -0x68(%rbp), %rax
movslq -0x5c(%rbp), %rcx
movl 0x4(%rax,%rcx,4), %eax
movl %eax, -0x6c(%rbp)
movl -0x54(%rbp), %eax
cmpl -0x6c(%rbp), %eax
jbe 0x2cb97
movq -0x10(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
movl -0x5c(%rbp), %ecx
addl $0x3, %ecx
movl $0x1, %r8d
callq 0x2c960
movl %eax, -0x3c(%rbp)
cmpl $0x0, -0x3c(%rbp)
jne 0x2cb78
cmpl $0x1, -0x5c(%rbp)
jne 0x2cb43
movl -0x54(%rbp), %eax
movl %eax, -0xa0(%rbp)
jmp 0x2cb50
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movl %eax, -0xa0(%rbp)
jmp 0x2cb50
movl -0xa0(%rbp), %edx
movq -0x68(%rbp), %rax
movslq -0x5c(%rbp), %rcx
movl %edx, 0x4(%rax,%rcx,4)
movq -0x10(%rbp), %rdi
movl -0x5c(%rbp), %esi
addl $0x3, %esi
movl $0x1, %edx
callq 0x29290
jmp 0x2cb95
cmpl $0x5, -0x3c(%rbp)
jne 0x2cb8e
movl -0x6c(%rbp), %eax
movl %eax, -0x54(%rbp)
movq $0x0, -0x20(%rbp)
jmp 0x2cb93
jmp 0x2ce9d
jmp 0x2cb95
jmp 0x2cb97
jmp 0x2cb99
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0x2cae7
movq -0x68(%rbp), %rax
movl (%rax), %eax
cmpl -0x54(%rbp), %eax
jae 0x2cde7
movq -0x10(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
movl $0x3, %ecx
movl $0x1, %r8d
callq 0x2c960
movl %eax, -0x3c(%rbp)
cmpl $0x0, %eax
jne 0x2cde7
movq -0x68(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x7c(%rbp)
movl -0x54(%rbp), %ecx
movq -0x68(%rbp), %rax
movl %ecx, 0x20(%rax)
cmpl $0x0, -0x2c(%rbp)
je 0x2cc0a
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
movl -0x2c(%rbp), %esi
callq 0x28e30
movl %eax, -0x3c(%rbp)
cmpl $0x0, -0x3c(%rbp)
jne 0x2cc64
movl -0x58(%rbp), %eax
movslq -0x40(%rbp), %rcx
imulq %rcx, %rax
movq %rax, -0x88(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
leaq -0x78(%rbp), %rsi
callq 0x2a040
movl %eax, -0x3c(%rbp)
cmpl $0x0, -0x3c(%rbp)
jne 0x2cc62
movq -0x78(%rbp), %rax
cmpq -0x88(%rbp), %rax
jge 0x2cc62
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
movl $0x5, %esi
leaq -0x88(%rbp), %rdx
callq 0x2ab90
jmp 0x2cc64
jmp 0x2cc66
xorl %eax, %eax
cmpl $0x0, -0x3c(%rbp)
movb %al, -0xa1(%rbp)
jne 0x2cc94
movq -0x48(%rbp), %rdi
leaq -0x4c(%rbp), %rsi
leaq -0x50(%rbp), %rdx
callq 0x2d160
movl %eax, %ecx
xorl %eax, %eax
cmpl %ecx, %eax
sete %al
movb %al, -0xa1(%rbp)
movb -0xa1(%rbp), %al
testb $0x1, %al
jne 0x2cca3
jmp 0x2cd49
movl -0x50(%rbp), %eax
cmpl -0x7c(%rbp), %eax
jbe 0x2ccbb
movl -0x50(%rbp), %eax
cmpl -0x54(%rbp), %eax
ja 0x2ccbb
movl -0x4c(%rbp), %eax
cmpl -0x58(%rbp), %eax
jbe 0x2ccbd
jmp 0x2cc66
movl -0x50(%rbp), %eax
subl $0x1, %eax
movl %eax, %eax
movl -0x40(%rbp), %ecx
addl $0x18, %ecx
movslq %ecx, %rcx
imulq %rcx, %rax
addq $0x20, %rax
addq $0x18, %rax
movq %rax, -0x90(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
movq -0x38(%rbp), %rsi
movl -0x40(%rbp), %edx
movq -0x90(%rbp), %rcx
callq 0x2a070
movl %eax, -0x3c(%rbp)
cmpl $0x0, -0x3c(%rbp)
je 0x2cd07
jmp 0x2cd49
movl -0x4c(%rbp), %eax
subl $0x1, %eax
movl %eax, %eax
movslq -0x40(%rbp), %rcx
imulq %rcx, %rax
movq %rax, -0x90(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x38(%rbp), %rsi
movl -0x40(%rbp), %edx
movq -0x90(%rbp), %rcx
callq 0x13070
movl %eax, -0x3c(%rbp)
cmpl $0x0, -0x3c(%rbp)
je 0x2cd44
jmp 0x2cd49
jmp 0x2cc66
cmpl $0x0, -0x3c(%rbp)
jne 0x2cdd4
movl -0x54(%rbp), %eax
movl %eax, -0xa8(%rbp)
movq -0x10(%rbp), %rdi
callq 0x298b0
movq %rax, %rcx
movl -0xa8(%rbp), %eax
movl 0x10(%rcx), %ecx
cmpl %ecx, %eax
jne 0x2cdc3
movq -0x10(%rbp), %rax
movl 0x5c(%rax), %eax
movslq -0x40(%rbp), %rcx
imulq %rcx, %rax
movq %rax, -0x98(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x98(%rbp), %rsi
callq 0x2a410
movl %eax, -0x3c(%rbp)
cmpl $0x0, -0x3c(%rbp)
jne 0x2cdc1
cmpl $0x0, -0x2c(%rbp)
je 0x2cdc1
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
movl -0x2c(%rbp), %esi
callq 0x28e30
movl %eax, -0x3c(%rbp)
jmp 0x2cdc3
cmpl $0x0, -0x3c(%rbp)
jne 0x2cdd2
movl -0x54(%rbp), %ecx
movq -0x68(%rbp), %rax
movl %ecx, (%rax)
jmp 0x2cdd4
movq -0x10(%rbp), %rdi
movl $0x3, %esi
movl $0x1, %edx
callq 0x29290
cmpl $0x5, -0x3c(%rbp)
jne 0x2cdf4
movl $0x0, -0x3c(%rbp)
jmp 0x2cdf6
cmpl $0x0, -0x3c(%rbp)
jne 0x2ce9b
cmpl $0x0, -0x14(%rbp)
je 0x2ce9b
movq -0x68(%rbp), %rax
movl (%rax), %eax
movq -0x10(%rbp), %rcx
cmpl 0x58(%rcx), %eax
jae 0x2ce22
movl $0x5, -0x3c(%rbp)
jmp 0x2ce99
cmpl $0x2, -0x14(%rbp)
jl 0x2ce97
movl $0x4, %edi
leaq -0x9c(%rbp), %rsi
callq 0xb4b0
movq -0x10(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
movl $0x4, %r8d
movl %r8d, %ecx
callq 0x2c960
movl %eax, -0x3c(%rbp)
cmpl $0x0, -0x3c(%rbp)
jne 0x2ce95
cmpl $0x3, -0x14(%rbp)
jne 0x2ce85
movq -0x10(%rbp), %rdi
movl -0x9c(%rbp), %esi
callq 0x291c0
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x2a410
movl %eax, -0x3c(%rbp)
movq -0x10(%rbp), %rdi
movl $0x4, %edx
movl %edx, %esi
callq 0x29290
jmp 0x2ce97
jmp 0x2ce99
jmp 0x2ce9b
jmp 0x2ce9d
movq -0x48(%rbp), %rdi
callq 0x2d260
movl -0x3c(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0xb0, %rsp
popq %rbp
retq
nopl (%rax,%rax)