// File: /workspace/github_c_makefile_star2_O0/barabo[P]advanced-shell-history/src/sqlite3.c
// Function: unixShmLock
static int unixShmLock(
  sqlite3_file *fd,          /* Database file holding the shared memory */
  int ofst,                  /* First lock to acquire or release */
  int n,                     /* Number of locks to acquire or release */
  int flags                  /* What to do with the lock */
){
  unixFile *pDbFd = (unixFile*)fd;      /* Connection holding shared memory */
  unixShm *p = pDbFd->pShm;             /* The shared memory being locked */
  unixShm *pX;                          /* For looping over all siblings */
  unixShmNode *pShmNode = p->pShmNode;  /* The underlying file iNode */
  int rc = SQLITE_OK;                   /* Result code */
  u16 mask;                             /* Mask of locks to take or release */

  assert( pShmNode==pDbFd->pInode->pShmNode );
  assert( pShmNode->pInode==pDbFd->pInode );
  assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK );
  assert( n>=1 );
  assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED)
       || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE)
       || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
       || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
  assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
  assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 );
  assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 );

  mask = (1<<(ofst+n)) - (1<<ofst);
  assert( n>1 || mask==(1<<ofst) );
  sqlite3_mutex_enter(pShmNode->mutex);
  if( flags & SQLITE_SHM_UNLOCK ){
    u16 allMask = 0; /* Mask of locks held by siblings */

    /* See if any siblings hold this same lock */
    for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
      if( pX==p ) continue;
      assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 );
      allMask |= pX->sharedMask;
    }

    /* Unlock the system-level locks */
    if( (mask & allMask)==0 ){
      rc = unixShmSystemLock(pShmNode, F_UNLCK, ofst+UNIX_SHM_BASE, n);
    }else{
      rc = SQLITE_OK;
    }

    /* Undo the local locks */
    if( rc==SQLITE_OK ){
      p->exclMask &= ~mask;
      p->sharedMask &= ~mask;
    } 
  }else if( flags & SQLITE_SHM_SHARED ){
    u16 allShared = 0;  /* Union of locks held by connections other than "p" */

    /* Find out which shared locks are already held by sibling connections.
    ** If any sibling already holds an exclusive lock, go ahead and return
    ** SQLITE_BUSY.
    */
    for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
      if( (pX->exclMask & mask)!=0 ){
        rc = SQLITE_BUSY;
        break;
      }
      allShared |= pX->sharedMask;
    }

    /* Get shared locks at the system level, if necessary */
    if( rc==SQLITE_OK ){
      if( (allShared & mask)==0 ){
        rc = unixShmSystemLock(pShmNode, F_RDLCK, ofst+UNIX_SHM_BASE, n);
      }else{
        rc = SQLITE_OK;
      }
    }

    /* Get the local shared locks */
    if( rc==SQLITE_OK ){
      p->sharedMask |= mask;
    }
  }else{
    /* Make sure no sibling connections hold locks that will block this
    ** lock.  If any do, return SQLITE_BUSY right away.
    */
    for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
      if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){
        rc = SQLITE_BUSY;
        break;
      }
    }
  
    /* Get the exclusive locks at the system level.  Then if successful
    ** also mark the local connection as being locked.
    */
    if( rc==SQLITE_OK ){
      rc = unixShmSystemLock(pShmNode, F_WRLCK, ofst+UNIX_SHM_BASE, n);
      if( rc==SQLITE_OK ){
        assert( (p->sharedMask & mask)==0 );
        p->exclMask |= mask;
      }
    }
  }
  sqlite3_mutex_leave(pShmNode->mutex);
  OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n",
           p->id, getpid(), p->sharedMask, p->exclMask));
  return rc;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movl %edx, -0x10(%rbp)
movl %ecx, -0x14(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
movq 0x40(%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x38(%rbp)
movl $0x0, -0x3c(%rbp)
movl -0xc(%rbp), %ecx
addl -0x10(%rbp), %ecx
movl $0x1, %eax
shll %cl, %eax
movl -0xc(%rbp), %ecx
movl $0x1, %edx
shll %cl, %edx
movl %edx, %ecx
subl %ecx, %eax
movw %ax, -0x3e(%rbp)
movl -0x14(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x1d055
movw $0x0, -0x40(%rbp)
movq -0x38(%rbp), %rax
movq 0x38(%rax), %rax
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
je 0x1cfee
movq -0x30(%rbp), %rax
cmpq -0x28(%rbp), %rax
jne 0x1cfce
jmp 0x1cfe0
movq -0x30(%rbp), %rax
movzwl 0x12(%rax), %ecx
movzwl -0x40(%rbp), %eax
orl %ecx, %eax
movw %ax, -0x40(%rbp)
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x30(%rbp)
jmp 0x1cfbb
movzwl -0x3e(%rbp), %eax
movzwl -0x40(%rbp), %ecx
andl %ecx, %eax
cmpl $0x0, %eax
jne 0x1d019
movq -0x38(%rbp), %rdi
movl -0xc(%rbp), %edx
addl $0x78, %edx
movl -0x10(%rbp), %ecx
movl $0x2, %esi
callq 0x1eb90
movl %eax, -0x3c(%rbp)
jmp 0x1d020
movl $0x0, -0x3c(%rbp)
cmpl $0x0, -0x3c(%rbp)
jne 0x1d050
movzwl -0x3e(%rbp), %edx
xorl $-0x1, %edx
movq -0x28(%rbp), %rax
movzwl 0x14(%rax), %ecx
andl %edx, %ecx
movw %cx, 0x14(%rax)
movzwl -0x3e(%rbp), %edx
xorl $-0x1, %edx
movq -0x28(%rbp), %rax
movzwl 0x12(%rax), %ecx
andl %edx, %ecx
movw %cx, 0x12(%rax)
jmp 0x1d19d
movl -0x14(%rbp), %eax
andl $0x4, %eax
cmpl $0x0, %eax
je 0x1d10d
movw $0x0, -0x42(%rbp)
movq -0x38(%rbp), %rax
movq 0x38(%rax), %rax
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
je 0x1d0b9
movq -0x30(%rbp), %rax
movzwl 0x14(%rax), %eax
movzwl -0x3e(%rbp), %ecx
andl %ecx, %eax
cmpl $0x0, %eax
je 0x1d099
movl $0x5, -0x3c(%rbp)
jmp 0x1d0b9
movq -0x30(%rbp), %rax
movzwl 0x12(%rax), %ecx
movzwl -0x42(%rbp), %eax
orl %ecx, %eax
movw %ax, -0x42(%rbp)
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x30(%rbp)
jmp 0x1d076
cmpl $0x0, -0x3c(%rbp)
jne 0x1d0f0
movzwl -0x42(%rbp), %eax
movzwl -0x3e(%rbp), %ecx
andl %ecx, %eax
cmpl $0x0, %eax
jne 0x1d0e7
movq -0x38(%rbp), %rdi
movl -0xc(%rbp), %edx
addl $0x78, %edx
movl -0x10(%rbp), %ecx
xorl %esi, %esi
callq 0x1eb90
movl %eax, -0x3c(%rbp)
jmp 0x1d0ee
movl $0x0, -0x3c(%rbp)
jmp 0x1d0f0
cmpl $0x0, -0x3c(%rbp)
jne 0x1d108
movzwl -0x3e(%rbp), %edx
movq -0x28(%rbp), %rax
movzwl 0x12(%rax), %ecx
orl %edx, %ecx
movw %cx, 0x12(%rax)
jmp 0x1d19b
movq -0x38(%rbp), %rax
movq 0x38(%rax), %rax
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
je 0x1d15f
movq -0x30(%rbp), %rax
movzwl 0x14(%rax), %eax
movzwl -0x3e(%rbp), %ecx
andl %ecx, %eax
cmpl $0x0, %eax
jne 0x1d146
movq -0x30(%rbp), %rax
movzwl 0x12(%rax), %eax
movzwl -0x3e(%rbp), %ecx
andl %ecx, %eax
cmpl $0x0, %eax
je 0x1d14f
movl $0x5, -0x3c(%rbp)
jmp 0x1d15f
jmp 0x1d151
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x30(%rbp)
jmp 0x1d119
cmpl $0x0, -0x3c(%rbp)
jne 0x1d199
movq -0x38(%rbp), %rdi
movl -0xc(%rbp), %edx
addl $0x78, %edx
movl -0x10(%rbp), %ecx
movl $0x1, %esi
callq 0x1eb90
movl %eax, -0x3c(%rbp)
cmpl $0x0, -0x3c(%rbp)
jne 0x1d197
movzwl -0x3e(%rbp), %edx
movq -0x28(%rbp), %rax
movzwl 0x14(%rax), %ecx
orl %edx, %ecx
movw %cx, 0x14(%rax)
jmp 0x1d199
jmp 0x1d19b
jmp 0x1d19d
movl -0x3c(%rbp), %eax
addq $0x50, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)