KiCheckForThreadDispatch

VOID __stdcall KiCheckForThreadDispatch(_KPRCB *Prcb, UINT8 OldIrql){
  __int64 v2; 
  unsigned __int64 v4; 
  ULONG_PTR v5; 
  bool v6; 
  __int64 v7; 
  __int64 v8; 
  UINT64 SpinCount; 
  v2 = *((_QWORD *)Prcb + 2);
  v4 = OldIrql;
  if( OldIrql >= 2u )
  {
    if( v2 && !*((_BYTE *)Prcb + 12586) )
      KiRequestSoftwareInterrupt(Prcb, 2);
  }
  else
  {
    v5 = *((_QWORD *)Prcb + 1);
    if( v2 )
    {
      KiAbProcessContextSwitch(*((_KTHREAD **)Prcb + 1), 0i64);
      LODWORD(SpinCount) = 0;
      while( _interlockedbittestandset64((volatile signed __int32 *)Prcb + 12, 0i64) )
      {
        do
          KeYieldProcessorEx(&SpinCount);
        while( *((_QWORD *)Prcb + 6) );
      }
      v7 = *((_QWORD *)Prcb + 2);
      *((_QWORD *)Prcb + 2) = 0i64;
      _disable();
      KiEndThreadCycleAccumulation(Prcb, (_KTHREAD *)v5, 0i64);
      _enable();
      *((_QWORD *)Prcb + 1) = v7;
      if( *(_BYTE *)(v7 + 388) == 1 )
        *(_DWORD *)(v7 + 132) = *(_DWORD *)(v7 + 132) - *(_DWORD *)(v7 + 436) + KUSER_SHARED_DATA.TickCount.LowPart;
      *(_BYTE *)(v7 + 388) = 2;
      *(_BYTE *)(v5 + 643) = 32;
      *(_BYTE *)(v5 + 390) = v4;
      KiQueueReadyThread((__int64)Prcb, v5, v8);
      v6 = !KiSwapContext((PKTHREAD)v5, (PKTHREAD)v7);
    }
    else
    {
      v6 = (*(_DWORD *)(v5 + 116) & 0x40) == 0;
    }
    if( !v6 )
    {
      __writecr8(1ui64);
      *(_DWORD *)(v5 + 116) &= ~0x40u;
      KiDeliverApc(0, 0i64, 0i64);
    }
    __writecr8(v4);
  }
}

Referenced by:

KeGenericProcessorCallback
KeRemoveQueueEx
KeWaitForMultipleObjects
KeWaitForSingleObject
KiAbProcessContextSwitch
KiBeginThreadWait
KiExitThreadWait
KiFastReadyThread