KiCheckForThreadDispatch
VOID __stdcall KiCheckForThreadDispatch(_KPRCB *Prcb, UINT8 OldIrql){
_ETHREAD *NextThread;
unsigned __int64 v4;
_ETHREAD *CurrentThread;
bool v6;
INT64 v7;
_ETHREAD *v8;
char v9;
INT64 v10;
INT64 v11;
INT64 v12;
UINT64 SpinCount;
NextThread = Prcb->NextThread;
v4 = OldIrql;
if( OldIrql >= 2u )
{
if( NextThread && !Prcb->DpcRoutineActive )
KiRequestSoftwareInterrupt(Prcb, 2);
}
else
{
CurrentThread = Prcb->CurrentThread;
if( NextThread )
{
KiAbProcessContextSwitch(&Prcb->CurrentThread->Tcb, 0i64);
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&Prcb->PrcbLock, 0i64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( Prcb->PrcbLock );
}
v8 = Prcb->NextThread;
Prcb->NextThread = 0i64;
_disable();
KiEndThreadCycleAccumulation((INT64)Prcb, (INT64)CurrentThread, 0i64, v7, v10, v11, v12);
_enable();
Prcb->CurrentThread = v8;
if( v8->Tcb.WaitBlockFill6[68] == 1 )
v8->Tcb.ReadyTime = v8->Tcb.ReadyTime - v8->Tcb.WaitBlock[2].SpareLong + KUSER_SHARED_DATA.TickCount.LowPart;
v8->Tcb.WaitBlockFill6[68] = 2;
CurrentThread->Tcb.WaitReason = 32;
CurrentThread->Tcb.WaitIrql = v4;
KiQueueReadyThread(Prcb, &CurrentThread->Tcb);
KiSwapContext();
v6 = v9 == 0;
}
else
{
v6 = (CurrentThread->Tcb._bf_0 & 0x40) == 0;
}
if( !v6 )
{
__writecr8(1ui64);
CurrentThread->Tcb._bf_0 &= ~0x40u;
KiDeliverApc(0, 0i64, 0i64);
}
__writecr8(v4);
}
}Referenced by:
KeGenericProcessorCallback
KeRemoveQueueEx
KeWaitForMultipleObjects
KeWaitForSingleObject
KiAbProcessContextSwitch
KiBeginThreadWait
KiExitThreadWait
KiFastReadyThread