KiGroupSchedulingQuantumEnd
VOID __stdcall KiGroupSchedulingQuantumEnd(
_KPRCB *Prcb,
_ETHREAD *Thread,
UINT8 RoundRobin,
_SINGLE_LIST_ENTRY *ReadyList){
_KPRCB *v4;
unsigned __int64 TickCountQuad;
char v8;
struct _KPRCB *CurrentPrcb;
char v10;
_ETHREAD *NextThread;
_KSCB *SchedulingGroup;
_KSCHEDULING_GROUP *volatile v13;
_KSCHEDULING_GROUP *v14;
_KSCB *v15;
char v16;
char v17;
_KSCB *v18;
_ETHREAD *v19;
INT64 v20;
int v21;
_ETHREAD *v22;
_KPRCB *v23;
_ETHREAD *v24;
struct _KPRCB *v25;
_DWORD *v26;
_ETHREAD *v27;
_KPRCB *v28;
_DWORD *SchedulerAssist;
char v30;
_BYTE *v31;
UINT8 v32;
INT64 v33;
UINT8 IsThreadRankNonZero;
char Priority;
_BYTE *v36;
INT64 v37;
bool v38;
_KSCB *v39;
_KSCB *v40;
int v41;
char ShareRankNonZero[4];
UINT64 SpinCount;
_KSCHEDULING_GROUP *volatile v44;
_ETHREAD *Threada;
char v46;
v4 = 0i64;
v44 = 0i64;
ShareRankNonZero[0] = 0;
v46 = 0;
TickCountQuad = KUSER_SHARED_DATA.TickCountQuad;
v8 = 0;
CurrentPrcb = KeGetCurrentPrcb();
v10 = 0;
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];
}
NextThread = Prcb->NextThread;
SchedulingGroup = 0i64;
Threada = NextThread;
if( NextThread )
{
SchedulingGroup = (_KSCB *)NextThread->Tcb.SchedulingGroup;
if( SchedulingGroup )
SchedulingGroup = (_KSCB *)((char *)SchedulingGroup + Prcb->ScbOffset);
}
if( TickCountQuad > Prcb->GenerationTarget )
{
KiGroupSchedulingGenerationEnd(Prcb, TickCountQuad, 0);
return;
}
v13 = Thread->Tcb.SchedulingGroup;
v14 = v13;
v44 = v13;
if( v13 )
{
v15 = (_KSCB *)((char *)v13 + Prcb->ScbOffset);
if( v15 )
{
while( 1 )
{
v16 = *((_BYTE *)v15 + 112);
if( (v16 & 4) != 0 )
break;
KiComputeGroupSchedulingRank(v14, Prcb, v15);
if( (*((_BYTE *)v15 + 112) & 4) == 0 )
goto LABEL_16;
v10 = 1;
v8 = 1;
if( SchedulingGroup != v15 )
goto LABEL_16;
v17 = 1;
v46 = 1;
LABEL_17:
v15 = v15->Parent;
if( !v15 )
{
v18 = (_KSCB *)Thread->Tcb.SchedulingGroup;
v19 = Threada;
if( v18 )
v18 = (_KSCB *)((char *)v18 + Prcb->ScbOffset);
if( !v10 || Threada )
{
if( v8 && Threada && SchedulingGroup )
{
if( SchedulingGroup == v18 )
goto LABEL_39;
while( SchedulingGroup )
{
SchedulingGroup = SchedulingGroup->Parent;
if( SchedulingGroup == v18 )
goto LABEL_39;
}
if( !v18 || v17 )
{
LABEL_39:
v27 = (_ETHREAD *)KiChooseLowestRankedThread(
Prcb,
&Threada->Tcb,
(unsigned int)(Threada->Tcb.Priority + 1));
if( v27 )
{
v19->Tcb.WaitBlockFill6[68] = 1;
v19->Tcb.WaitBlock[2].SpareLong = KUSER_SHARED_DATA.TickCount.LowPart;
if( (v27->Tcb.gap0[2] & 4) == 0
|| (IsThreadRankNonZero = KiIsThreadRankNonZero(&v27->Tcb, Prcb, v28),
Priority = 1,
!IsThreadRankNonZero) )
{
Priority = v27->Tcb.Priority;
}
*Prcb->PriorityState = Priority;
v36 = Prcb->SchedulerAssist;
if( v36 )
{
v37 = (unsigned int)KiVpThreadSystemWorkPriority;
if( v27 != Prcb->IdleThread )
v37 = (unsigned int)Priority;
KiSetSchedulerAssistPriority((INT32 *)Prcb->SchedulerAssist, v37, 0);
v36 = Prcb->SchedulerAssist;
}
v38 = v27 == Prcb->IdleThread;
Prcb->NextThread = v27;
if( v36 )
v36[16] = v38;
if( v27->Tcb.WaitBlockFill6[68] == 1 )
v27->Tcb.ReadyTime = v27->Tcb.ReadyTime
- v27->Tcb.WaitBlock[2].SpareLong
+ KUSER_SHARED_DATA.TickCount.LowPart;
v27->Tcb.WaitBlockFill6[68] = 3;
v39 = (_KSCB *)v19->Tcb.SchedulingGroup;
if( v39 )
v39 = (_KSCB *)((char *)v39 + Prcb->ScbOffset);
KiGetThreadEffectiveRankNonZero(v19, v39, v28, 1u, (UINT8 *)ShareRankNonZero);
if( v41 )
KiAddThreadToScbQueue(Prcb, v40, &v19->Tcb, 1ui64);
else
KiAddThreadToPrcbQueue(Prcb, &v19->Tcb, (unsigned int)v19->Tcb.Priority, 1ui64, ShareRankNonZero[0]);
}
}
}
}
else
{
KiGetThreadEffectiveRankNonZero(Thread, v18, v4, 1u, 0i64);
v20 = (unsigned int)Thread->Tcb.Priority;
if( v21 )
v22 = (_ETHREAD *)KiChooseLowestRankedThread(Prcb, &Thread->Tcb, (unsigned int)v20);
else
v22 = (_ETHREAD *)KiSelectReadyThread(v20, Prcb);
v24 = v22;
if( v22 )
{
if( (v22->Tcb.gap0[2] & 4) == 0 || (v32 = KiIsThreadRankNonZero(&v22->Tcb, Prcb, v23), v30 = 1, !v32) )
v30 = v24->Tcb.Priority;
*Prcb->PriorityState = v30;
v31 = Prcb->SchedulerAssist;
if( v31 )
{
v33 = (unsigned int)KiVpThreadSystemWorkPriority;
if( v24 != Prcb->IdleThread )
v33 = (unsigned int)v30;
KiSetSchedulerAssistPriority((INT32 *)Prcb->SchedulerAssist, v33, 0);
v31 = Prcb->SchedulerAssist;
}
Prcb->NextThread = v24;
if( v31 )
v31[16] = v24 == Prcb->IdleThread;
if( v24->Tcb.WaitBlockFill6[68] == 1 )
v24->Tcb.ReadyTime = v24->Tcb.ReadyTime
- v24->Tcb.WaitBlock[2].SpareLong
+ KUSER_SHARED_DATA.TickCount.LowPart;
v24->Tcb.WaitBlockFill6[68] = 3;
}
}
if( v18 )
{
if( KiShouldPreemptionBeDeferred(&Thread->Tcb) )
{
if( (*(&Thread->Tcb.MiscFlags + 1) & 0xC00) == 0 )
{
_InterlockedAnd64((volatile signed __int64 *)&Prcb->PrcbLock, 0i64);
KiInsertDeferredPreemptionApc(Prcb, &Thread->Tcb, 0);
v25 = KeGetCurrentPrcb();
HIDWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&Prcb->PrcbLock, 0i64) )
{
do
KeYieldProcessorEx((UINT64 *)((char *)&SpinCount + 4));
while( Prcb->PrcbLock );
v26 = v25->SchedulerAssist;
if( v26 )
{
if( v25->NestingLevel <= 1u )
++v26[6];
}
}
}
}
else if( KiCheckForMaxOverQuotaScb(v18) && !Prcb->NextThread )
{
KiSelectNextThread(Prcb, ReadyList);
}
}
return;
}
v14 = (_KSCHEDULING_GROUP *)((char *)v15 - Prcb->ScbOffset);
v44 = v14;
}
if( (v16 & 2) == 0 )
{
if( KiCheckMaxOverQuotaTransition(v15, v14) )
{
if( (*((_BYTE *)v15 + 112) & 1) != 0 )
KiRemoveSchedulingGroupQueue(Prcb, v15, 1u);
}
else
{
if( v15->GenerationCycles < v15->RankCycleTarget )
{
if( RoundRobin )
v10 = 1;
goto LABEL_16;
}
KiRecomputeGroupSchedulingRank(v14, v15, Prcb);
if( SchedulingGroup == v15 )
{
v10 = 1;
v46 = 1;
v8 = 1;
goto LABEL_16;
}
}
}
v10 = 1;
v8 = 1;
LABEL_16:
v17 = v46;
goto LABEL_17;
}
}
}Referenced by:
KiQuantumEnd