KiTransitionSchedulingGroupGeneration
VOID __stdcall KiTransitionSchedulingGroupGeneration(_KPRCB *Prcb, UINT64 CurrentTick, UINT8 Parking){
UINT8 v4;
unsigned __int64 GenerationTarget;
unsigned int v6;
__int64 v7;
_ETHREAD *NextThread;
_KSCHEDULING_GROUP *volatile SchedulingGroup;
_LIST_ENTRY *p_ScbList;
_LIST_ENTRY *Flink;
char v12;
_LIST_ENTRY **p_Blink;
__int64 v14;
__int64 v15;
_KSCHEDULING_GROUP *v16;
_KPRCB *v17;
volatile signed __int32 *v18;
unsigned int v19;
unsigned int v20;
unsigned int v21;
unsigned __int64 MaxQuotaLimitCycles;
__int64 v23;
__int64 v24;
UINT8 IsThreadRankNonZero;
char Priority;
INT32 *SchedulerAssist;
__int64 v28;
__int64 v29;
_QWORD *v30;
_ETHREAD *v31;
_ETHREAD *v32;
INT64 v33;
__int64 Number;
_ETHREAD *Thread;
_KSCHEDULING_GROUP *v36;
UINT8 ShareRankNonZero;
char v38;
UINT8 v39;
int v40;
v39 = Parking;
v4 = Parking;
GenerationTarget = Prcb->GenerationTarget;
v6 = 1;
if( CurrentTick > GenerationTarget )
v6 = (CurrentTick - 1 + (unsigned int)KiGenerationTicks - GenerationTarget) / (unsigned int)KiGenerationTicks + 1;
v7 = 0i64;
Prcb->GenerationTarget = *(&KiSwapEvent + 41);
Prcb->ScbQueue.Root = 0i64;
Prcb->ScbQueue.Min = 0i64;
NextThread = Prcb->NextThread;
v38 = 0;
Thread = NextThread;
if( !NextThread )
{
NextThread = Prcb->CurrentThread;
Thread = NextThread;
}
SchedulingGroup = NextThread->Tcb.SchedulingGroup;
v36 = SchedulingGroup;
if( SchedulingGroup )
{
SchedulingGroup = (_KSCHEDULING_GROUP *volatile)((char *)SchedulingGroup + Prcb->ScbOffset);
v36 = SchedulingGroup;
}
p_ScbList = &Prcb->ScbList;
Flink = Prcb->ScbList.Flink;
if( Flink == &Prcb->ScbList )
{
LABEL_26:
if( Prcb->GroupSchedulingOverQuota )
{
Number = Prcb->Number;
Prcb->GroupSchedulingOverQuota = 0;
_InterlockedAnd64(
(volatile signed __int64 *)&KiGroupSchedulingOverQuotaMask.Bitmap[(unsigned __int64)(unsigned int)KiProcessorIndexToNumberMappingTable[Number] >> 6],
~(1i64 << (KiProcessorIndexToNumberMappingTable[Number] & 0x3F)));
}
return;
}
v12 = v6;
do
{
p_Blink = &Flink[-5].Blink;
if( v6 >= 0x40 )
v14 = v7;
else
v14 = (_QWORD)p_Blink[6] << v12;
v15 = v14 | 1;
if( ((_BYTE)p_Blink[14] & 4) == 0 )
v15 = v14;
p_Blink[6] = (_LIST_ENTRY *)v15;
v16 = (_KSCHEDULING_GROUP *)((char *)p_Blink - Prcb->ScbOffset);
KiChargeSchedulingGroupCycleTime(v16, (_KSCB *)&Flink[-5].Blink);
if( !v4 )
{
if( Prcb->ClockOwner )
{
if( ((_BYTE)p_Blink[14] & 0x10) == 0 )
{
MaxQuotaLimitCycles = v16->MaxQuotaLimitCycles;
v23 = MaxQuotaLimitCycles + _InterlockedExchangeAdd64(&v16->MaxQuotaCyclesRemaining, MaxQuotaLimitCycles);
v24 = v16->MaxQuotaLimitCycles;
if( v23 > v24 )
_InterlockedExchange64(&v16->MaxQuotaCyclesRemaining, v24);
}
}
}
if( p_Blink[1] != p_Blink[2] )
{
v17 = (_KPRCB *)((unsigned int)KiGroupSchedulingNumerator * ((unsigned __int64)*p_Blink >> 10)
+ (((unsigned __int64)p_Blink[4] * (unsigned int)(1024 - KiGroupSchedulingNumerator)) >> 10));
p_Blink[4] = (_LIST_ENTRY *)v17;
}
v18 = (volatile signed __int32 *)p_Blink[15];
v7 = 0i64;
*p_Blink = 0i64;
p_Blink[5] = 0i64;
if( v18 )
{
v19 = ((*((unsigned __int8 *)p_Blink + 112) >> 3) & 1) - *((_DWORD *)p_Blink + 29);
if( (int)(v19 + _InterlockedExchangeAdd(v18, v19)) < 0 )
LODWORD(p_Blink[15]->Flink) = 0;
}
v20 = *((unsigned __int8 *)p_Blink + 112);
p_Blink[3] = 0i64;
*((_BYTE *)p_Blink + 112) = v20 & 0xFC;
*((_DWORD *)p_Blink + 29) = (v20 >> 3) & 1;
*(_OWORD *)(p_Blink + 11) = 0i64;
p_Blink[13] = 0i64;
p_Blink[49] = 0i64;
p_Blink[50] = 0i64;
if( !*((_DWORD *)p_Blink + 29) )
{
*((_BYTE *)p_Blink + 112) &= ~4u;
if( p_Blink == (_LIST_ENTRY **)SchedulingGroup )
{
if( (Thread->Tcb.gap0[2] & 4) != 0 )
{
IsThreadRankNonZero = KiIsThreadRankNonZero(&Thread->Tcb, Prcb, v17);
Priority = 1;
if( !IsThreadRankNonZero )
Priority = Thread->Tcb.Priority;
v7 = 0i64;
}
else
{
Priority = Thread->Tcb.Priority;
}
*Prcb->PriorityState = Priority;
SchedulerAssist = (INT32 *)Prcb->SchedulerAssist;
if( SchedulerAssist )
{
if( Thread == Prcb->IdleThread )
v33 = (unsigned int)KiVpThreadSystemWorkPriority;
else
v33 = (unsigned int)Priority;
KiSetSchedulerAssistPriority(SchedulerAssist, v33, 0);
}
}
LABEL_22:
v21 = *((unsigned __int16 *)p_Blink + 57);
v40 = v7;
ShareRankNonZero = 0;
if( v21 )
{
do
{
_BitScanReverse((unsigned int *)&v28, v21);
v21 ^= 1 << v28;
v40 = v28;
v29 = (__int64)&p_Blink[2 * v28 + 17];
v30 = *(_QWORD **)v29;
do
{
*((_DWORD *)v30 - 25) &= ~0x2000u;
v31 = (_ETHREAD *)(v30 - 27);
v30[91] = 0i64;
v30 = (_QWORD *)*v30;
KiGetThreadEffectiveRankNonZero(v31, (_KSCB *)&Flink[-5].Blink, v17, 0, &ShareRankNonZero);
KiAddThreadToPrcbQueue(Prcb, &v32->Tcb, (unsigned int)v32->Tcb.Priority, 0i64, ShareRankNonZero);
}
while( v30 != (_QWORD *)v29 );
*(_QWORD *)(v29 + 8) = v29;
*(_QWORD *)v29 = v29;
}
while( v21 );
SchedulingGroup = v36;
p_ScbList = &Prcb->ScbList;
v4 = v39;
v7 = 0i64;
}
*((_WORD *)p_Blink + 57) = v7;
goto LABEL_24;
}
if( v4 )
goto LABEL_22;
if( *((_WORD *)p_Blink + 57) )
{
KiInsertNonMaxOverQuotaScb((_KSCB *)&Flink[-5].Blink, Prcb, 0);
v7 = 0i64;
v38 = 1;
}
LABEL_24:
Flink = Flink->Flink;
v12 = v6;
}
while( Flink != p_ScbList );
if( !v38 )
goto LABEL_26;
}Referenced by:
KiGroupSchedulingGenerationEnd