KiDeferGroupSchedulingPreemption
VOID __fastcall KiDeferGroupSchedulingPreemption(_ETHREAD *CurrentThread, _KPRCB *CurrentPrcb){
int v4;
_ETHREAD *NextThread;
_KPRCB *v6;
_KSCB *SchedulingGroup;
UINT8 IsThreadRankNonZero;
char Priority;
int v10;
INT64 v11;
UINT8 ShareRankNonZero;
UINT64 SpinCount;
if( CurrentThread->Tcb.SchedulingGroup && KiShouldPreemptionBeDeferred(&CurrentThread->Tcb) )
{
v4 = 0;
LODWORD(SpinCount) = 0;
ShareRankNonZero = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&CurrentPrcb->PrcbLock, 0i64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( CurrentPrcb->PrcbLock );
}
NextThread = CurrentPrcb->NextThread;
if( CurrentThread->Tcb.SchedulingGroup
&& NextThread != CurrentPrcb->IdleThread
&& (unsigned int)KiPrcbInGroupAffinity(CurrentPrcb, &CurrentThread->Tcb.Affinity)
&& ((SchedulingGroup = (_KSCB *)NextThread->Tcb.SchedulingGroup) != 0i64
&& (SchedulingGroup = (_KSCB *)((char *)SchedulingGroup + CurrentPrcb->ScbOffset)) != 0i64
&& (KiGetThreadEffectiveRankNonZero(NextThread, SchedulingGroup, v6, 1u, &ShareRankNonZero), (v4 = v10) != 0)
|| NextThread->Tcb.Priority <= CurrentThread->Tcb.Priority) )
{
CurrentPrcb->NextThread = 0i64;
if( (CurrentThread->Tcb.gap0[2] & 4) == 0
|| (IsThreadRankNonZero = KiIsThreadRankNonZero(&CurrentThread->Tcb, CurrentPrcb, v6),
Priority = 1,
!IsThreadRankNonZero) )
{
Priority = CurrentThread->Tcb.Priority;
}
*CurrentPrcb->PriorityState = Priority;
if( CurrentPrcb->SchedulerAssist )
{
v11 = (unsigned int)KiVpThreadSystemWorkPriority;
if( CurrentThread != CurrentPrcb->IdleThread )
v11 = (unsigned int)Priority;
KiSetSchedulerAssistPriority((INT32 *)CurrentPrcb->SchedulerAssist, v11, 0);
}
NextThread->Tcb.WaitBlockFill6[68] = 1;
if( v4 )
KiAddThreadToScbQueue(CurrentPrcb, SchedulingGroup, &NextThread->Tcb, 1ui64);
else
KiAddThreadToPrcbQueue(
CurrentPrcb,
&NextThread->Tcb,
(unsigned int)NextThread->Tcb.Priority,
1ui64,
ShareRankNonZero);
_InterlockedAnd64((volatile signed __int64 *)&CurrentPrcb->PrcbLock, 0i64);
KiInsertDeferredPreemptionApc(CurrentPrcb, &CurrentThread->Tcb, 0);
}
else
{
_InterlockedAnd64((volatile signed __int64 *)&CurrentPrcb->PrcbLock, 0i64);
}
}
}Referenced by:
KiDispatchInterrupt