KeReleaseSemaphore

NTSTATUS __stdcall KeReleaseSemaphore(_KSEMAPHORE *Semaphore, INT64 Increment, INT64 Adjustment, UINT8 Wait){
  int v4; 
  unsigned int v5; 
  UINT8 OldIrql; 
  _KPRCB *CurrentPrcb; 
  NTSTATUS v9; 
  NTSTATUS v10; 
  _KSEMAPHORE *v11; 
  __int64 v12; 
  _KWAIT_BLOCK *v13; 
  _LIST_ENTRY *Blink; 
  unsigned __int8 WaitType; 
  bool v16; 
  UINT64 v17; 
  _QWORD *v19; 
  _ETHREAD *v20; 
  char v21; 
  int v22; 
  _KWAIT_BLOCK **QuantumTarget; 
  _BOOL4 v24; 
  _QWORD *v25; 
  _KPRCB *Prcb; 
  _ETHREAD *CurrentThread; 
  _ETHREAD *Object; 

  v4 = Adjustment;
  v5 = Increment;
  v24 = Wait != 0;
  OldIrql = KeGetCurrentIrql();
  __writecr8(2ui64);
  CurrentPrcb = KeGetCurrentPrcb();
  KiAcquireKobjectLockSafe(Semaphore);
  v9 = *(_DWORD *)&Semaphore->gap0[4];
  v10 = v9 + v4;
  if( v9 + v4 > Semaphore->Limit || v10 < v9 )
  {
    _InterlockedAnd((volatile signed __int32 *)Semaphore, 0xFFFFFF7F);
    __writecr8(OldIrql);
    RtlRaiseStatus(-1073741753);
  }
  *(_DWORD *)&Semaphore->gap0[4] = v10;
  if( !v9 )
  {
    v11 = *(_KSEMAPHORE **)&Semaphore->gap0[8];
    while( v11 != (_KSEMAPHORE *)&Semaphore->gap0[8] )
    {
      v12 = *(_QWORD *)v11->gap0;
      v13 = (_KWAIT_BLOCK *)v11;
      v11 = (_KSEMAPHORE *)v12;
      Blink = v13->WaitListEntry.Blink;
      if( *(_KWAIT_BLOCK **)(v12 + 8) != v13 || (_KWAIT_BLOCK *)Blink->Flink != v13 )
LABEL_6:
        __fastfail(3u);
      Blink->Flink = (_LIST_ENTRY *)v12;
      *(_QWORD *)(v12 + 8) = Blink;
      WaitType = v13->WaitType;
      if( WaitType == 1 )
      {
        if( KiTryUnwaitThread(CurrentPrcb, v13, v13->WaitKey, 0i64) )
        {
          v16 = (*(_DWORD *)&Semaphore->gap0[4])-- == 1;
          if( v16 )
            break;
        }
      }
      else
      {
        if( WaitType == 2 )
        {
          v13->BlockState = 5;
          Object = v13->Thread;
          v25 = &Object->Tcb.gap0[8];
          v13->WaitListEntry.Flink = 0i64;
          KeGetCurrentIrql();
          __writecr8(2ui64);
          Prcb = KeGetCurrentPrcb();
          CurrentThread = Prcb->CurrentThread;
          KiAcquireKobjectLockSafe(Object);
          v19 = v25;
          v20 = Object;
          if( (_QWORD *)*v19 == v19
            || LODWORD(Object->Tcb.InitialStack) >= HIDWORD(Object->Tcb.InitialStack)
            || (_ETHREAD *)CurrentThread->Tcb.Queue == Object && CurrentThread->Tcb.WaitReason == 15 )
          {
LABEL_25:
            v22 = *(_DWORD *)&v20->Tcb.gap0[4];
            *(_DWORD *)&v20->Tcb.gap0[4] = v22 + 1;
            QuantumTarget = (_KWAIT_BLOCK **)v20->Tcb.QuantumTarget;
            if( *QuantumTarget != (_KWAIT_BLOCK *)&v20->Tcb.SListFaultAddress )
              goto LABEL_6;
            v13->WaitListEntry.Flink = (_LIST_ENTRY *)&v20->Tcb.SListFaultAddress;
            v13->WaitListEntry.Blink = (_LIST_ENTRY *)QuantumTarget;
            *QuantumTarget = v13;
            v20->Tcb.QuantumTarget = (unsigned __int64)v13;
            if( !v22 && (_QWORD *)*v19 != v19 )
            {
              KiWakeOtherQueueWaiters(Prcb, (_KQUEUE *)v20);
              v20 = Object;
            }
          }
          else
          {
            KiWakeQueueWaiter(Prcb, (_KQUEUE *)Object, (INT64)v13);
            v20 = Object;
            if( !v21 )
            {
              v19 = &Object->Tcb.gap0[8];
              goto LABEL_25;
            }
          }
          _InterlockedAnd((volatile signed __int32 *)v20, 0xFFFFFF7F);
          v16 = (*(_DWORD *)&Semaphore->gap0[4])-- == 1;
          if( v16 )
            break;
          continue;
        }
        KiTryUnwaitThread(CurrentPrcb, v13, 256i64, 0i64);
      }
    }
  }
  _InterlockedAnd((volatile signed __int32 *)Semaphore, 0xFFFFFF7F);
  v17 = 3i64;
  if( !v24 )
    v17 = 0i64;
  KiExitDispatcher(CurrentPrcb, v17, AdjustUnwait, v5, OldIrql);
  return v9;
}

Referenced by:

AlpcpDoPortCleanup
FsRtlDeregisterUncProvider
FsRtlpRegisterUncProvider
IopAllocateBootResources
IopInsertLegacyBusDeviceNode
IopLegacyResourceAllocation
IopQueryConflictList
IopUncacheInterfaceInformation
NtReleaseKeyedEvent
NtReleaseSemaphore
NtSignalAndWaitForSingleObject
NtWaitForKeyedEvent
PnpAllocateResources
PnpReallocateResources
PopIrpWorker
PopSystemIrpCompletion
PpProfileCancelHardwareProfileTransition
PpProfileCancelTransitioningDock
PpProfileCommitTransitioningDock