KiExitDispatcher

VOID __stdcall KiExitDispatcher(
        _KPRCB *Prcb,
        UINT64 Flags,
        _ADJUST_REASON AdjustReason,
        INT64 Increment,
        UINT8 OldIrql){
  char v5; 
  char v6; 
  char v7; 
  unsigned __int64 v9; 
  _ETHREAD *NextThread; 
  _ETHREAD *v11; 
  _SINGLE_LIST_ENTRY *Next; 
  __int64 v13; 
  _SINGLE_LIST_ENTRY *v14; 
  _SINGLE_LIST_ENTRY *v15; 
  _SINGLE_LIST_ENTRY *v16; 
  int v17; 
  int v18; 
  _SINGLE_LIST_ENTRY *v19; 
  _SINGLE_LIST_ENTRY *v20; 
  char v21; 
  _ETHREAD *CurrentThread; 
  UINT8 v23; 
  INT64 v24; 
  struct _KPRCB *CurrentPrcb; 
  _ETHREAD *v26; 
  char v27; 
  _SINGLE_LIST_ENTRY *v28; 
  signed __int64 *v29; 
  signed __int64 v30; 
  signed __int64 v31; 
  _DWORD *SchedulerAssist; 
  _SINGLE_LIST_ENTRY *v33; 
  INT64 v34; 
  INT64 v35; 
  INT64 r8_0; 
  UINT64 SpinCount; 

  v5 = Increment;
  v6 = Flags & 1;
  v7 = AdjustReason;
  if( Prcb->DeferredReadyListHead.Next )
  {
    if( v6 )
    {
      KiDirectSwitchThread(Prcb, (_BYTE *)(unsigned int)Increment, (Flags & 2) != 0);
      if( v21 )
        goto LABEL_29;
    }
    Next = Prcb->DeferredReadyListHead.Next;
    Prcb->DeferredReadyListHead.Next = 0i64;
    do
    {
      v13 = BYTE3(Next[46].Next);
      v14 = Next - 27;
      v15 = Next[-1].Next;
      Next = Next->Next;
      v16 = &v15[6 * v13];
      do
      {
        if( BYTE1(v15[2].Next) < 5u )
        {
          v33 = v15[4].Next;
          KiAcquireKobjectLockSafe(v33);
          if( BYTE1(v15[2].Next) == 4 )
          {
            v19 = v15->Next;
            v20 = v15[1].Next;
            if( v15->Next[1].Next != v15 || v20->Next != v15 )
              __fastfail(3u);
            v20->Next = v19;
            v19[1].Next = v20;
          }
          _InterlockedAnd((volatile signed __int32 *)v33, 0xFFFFFF7F);
        }
        v15 += 6;
      }
      while( v15 != v16 );
      BYTE6(v14[70].Next) = v7;
      HIBYTE(v14[70].Next) = v5;
      v17 = (int)v14[15].Next;
      if( (v17 & 0x20000) != 0 )
      {
        if( (v17 & 0x100000) == 0 )
          goto LABEL_15;
        _interlockedbittestandreset((volatile signed __int32 *)&v14[15], 0x14u);
        if( (_InterlockedExchangeAdd((volatile signed __int32 *)&v14[23].Next[105], 8u) & 7) == 0 )
          goto LABEL_15;
        v28 = v14[23].Next;
        KiAcquireKobjectLockSafe(v28);
        if( ((__int64)v28[105].Next & 7) == 0 )
        {
          _InterlockedAnd((volatile signed __int32 *)v28, 0xFFFFFF7F);
LABEL_15:
          v18 = (_DWORD)v14 + 216;
          r8_0 = 0i64;
          v14[27].Next = 0i64;
          while( 1 )
          {
            KiDeferredReadySingleThread((INT64)Prcb, v18 - 216, (INT64)&r8_0);
            v18 = r8_0;
            if( !r8_0 )
              break;
            r8_0 = *(_QWORD *)r8_0;
          }
          continue;
        }
      }
      else
      {
        v28 = v14[23].Next;
        KiAcquireKobjectLockSafe(v28);
        if( ((__int64)v28[105].Next & 7) == 0 )
        {
          _InterlockedExchangeAdd((volatile signed __int32 *)&v28[105], 8u);
          _InterlockedAnd((volatile signed __int32 *)v28, 0xFFFFFF7F);
          _interlockedbittestandreset((volatile signed __int32 *)&v14[15], 0x14u);
          BYTE4(v14[48].Next) = 6;
          v29 = (signed __int64 *)&v14[27];
          _m_prefetchw(&KiStackInSwapListHead);
          v30 = KiStackInSwapListHead;
          do
          {
            *v29 = v30;
            v31 = v30;
            v30 = _InterlockedCompareExchange64(&KiStackInSwapListHead, (signed __int64)v29, v30);
          }
          while( v30 != v31 );
          if( !v30 )
            KeSetEvent((PRKEVENT)&KiSwapEvent, 10, 0);
          continue;
        }
      }
      KiRequestProcessInSwap((_KTHREAD *)v14, (_KPROCESS *)v28);
    }
    while( Next );
  }
  if( v6 )
  {
LABEL_29:
    CurrentThread = Prcb->CurrentThread;
    v23 = OldIrql;
    CurrentThread->Tcb._bf_0 |= 4u;
    CurrentThread->Tcb.WaitIrql = v23;
    return;
  }
  v9 = OldIrql;
  NextThread = Prcb->NextThread;
  if( OldIrql < 2u )
  {
    v11 = Prcb->CurrentThread;
    if( NextThread )
    {
      KiAbProcessContextSwitch(&Prcb->CurrentThread->Tcb, 0i64);
      CurrentPrcb = KeGetCurrentPrcb();
      LODWORD(SpinCount) = 0;
      while( _interlockedbittestandset64((volatile signed __int32 *)&Prcb->PrcbLock, 0i64) )
      {
        do
          KeYieldProcessorEx(&SpinCount);
        while( Prcb->PrcbLock );
        SchedulerAssist = CurrentPrcb->SchedulerAssist;
        if( SchedulerAssist && CurrentPrcb->NestingLevel <= 1u )
          ++SchedulerAssist[6];
      }
      v26 = Prcb->NextThread;
      Prcb->NextThread = 0i64;
      _disable();
      KiEndThreadCycleAccumulation((INT64)Prcb, (INT64)v11, 0i64, v24, (INT64)v33, v34, v35);
      _enable();
      Prcb->CurrentThread = v26;
      if( v26->Tcb.WaitBlockFill6[68] == 1 )
        v26->Tcb.ReadyTime = v26->Tcb.ReadyTime - v26->Tcb.WaitBlock[2].SpareLong + KUSER_SHARED_DATA.TickCount.LowPart;
      v26->Tcb.WaitBlockFill6[68] = 2;
      v11->Tcb.WaitReason = 32;
      v11->Tcb.WaitIrql = v9;
      KiQueueReadyThread(Prcb, &v11->Tcb);
      KiSwapContext();
      if( !v27 )
        goto LABEL_6;
    }
    else if( (v11->Tcb._bf_0 & 0x40) == 0 )
    {
LABEL_6:
      __writecr8(v9);
      return;
    }
    __writecr8(1ui64);
    v11->Tcb._bf_0 &= ~0x40u;
    KiDeliverApc(0, 0i64, 0i64);
    goto LABEL_6;
  }
  if( NextThread && !Prcb->DpcRoutineActive )
    KiRequestSoftwareInterrupt(Prcb, 2);
}

Referenced by:

CcUnpinFileDataEx
ExpQueueWorkItem
ExpReleaseResourceExclusiveForThreadLite
ExpReleaseResourceSharedForThreadLite
ExpSetTimerObject
IoSetIoCompletionEx
IoSetIoCompletionEx2
IopfCompleteRequest
KeAdjustTimerDelayProcess
KeAlertThread
KeAlertThreadByThreadId
KeDeleteMutant
KeForceResumeProcess
KeForceResumeThread
KeFreezeProcess
KeInsertHeadQueue
KeInsertPriQueue
KeInsertQueue
KeInsertQueueApc
KeInsertQueueEx
KePulseEvent
KeRegisterObjectNotification
KeReleaseMutant
KeReleaseSemaphore
KeReleaseSemaphoreEx
KeRequestTerminationThread
KeResumeThread
KeRundownPriQueue
KeRundownQueueEx
KeSetEvent
KeSetEventBoostPriorityEx
KeSetProcess
KeSetTimerEx
KeSignalGate
KeSuspendThread
KeThawProcess
KeTimeOutQueueWaiters
KeWakeWaitChain
KiRundownMutants
KiSchedulerApc
KiSetSystemTimeDpc
KiSetTimerEx
NtAssociateWaitCompletionPacket
NtReleaseWorkerFactoryWorker
NtWaitForWorkViaWorkerFactory