KeSetSchedulingGroupRankBias
VOID __stdcall KeSetSchedulingGroupRankBias(_KSCHEDULING_GROUP *SchedulingGroup, UINT8 Enable){
int v2;
__int64 CurrentIrql;
struct _KPRCB *CurrentPrcb;
unsigned int v6;
__int64 v7;
_KSCB *v8;
char v9;
unsigned int Rank;
char v11;
ULONG_PTR v12;
bool v13;
unsigned int v14;
char v15;
unsigned int v16;
__int64 v17;
__int64 v18;
UINT8 v19;
_KSCB *v20;
_KSCB *Parent;
_SINGLE_LIST_ENTRY *p_ReadyList;
unsigned __int64 Root;
UINT64 v24;
UINT64 SpinCount;
_SINGLE_LIST_ENTRY ReadyList;
__int64 v27;
v2 = Enable;
ReadyList.Next = 0i64;
CurrentIrql = KeGetCurrentIrql();
v27 = CurrentIrql;
__writecr8(2ui64);
CurrentPrcb = KeGetCurrentPrcb();
v6 = 0;
if( (_DWORD)KeMaximumProcessors )
{
while( 1 )
{
v7 = (__int64)*(&KiProcessorBlock + v6);
v8 = &SchedulingGroup->PerProcessor[v6];
if( v7 )
{
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)(v7 + 48), 0i64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( *(_QWORD *)(v7 + 48) );
}
}
v9 = *((_BYTE *)v8 + 112);
Rank = v8->Rank;
if( (_BYTE)v2 )
break;
v14 = *((unsigned __int8 *)v8 + 112);
v15 = v9 & 0xF7;
*((_BYTE *)v8 + 112) = v15;
v16 = Rank - ((v14 >> 3) & 1);
v8->Rank = v16;
if( v16 )
{
if( (v15 & 1) == 0 )
goto LABEL_7;
v19 = 0;
goto LABEL_34;
}
if( v7 )
{
if( (v15 & 1) == 0 )
goto LABEL_25;
v20 = &SchedulingGroup->PerProcessor[v6];
do
{
Parent = v20->Parent;
if( !Parent )
break;
v20 = v20->Parent;
}
while( !Parent->Rank );
if( v20->Rank )
{
p_ReadyList = 0i64;
}
else
{
p_ReadyList = &ReadyList;
v20 = 0i64;
}
KiMoveScbThreadsToNewReadylist(v8, v20, 0i64, p_ReadyList);
Root = (unsigned __int64)v8->ChildScbQueue.Root;
if( (*(_BYTE *)&v8->ChildScbQueue.0 & 1) != 0 )
{
if( Root )
{
Root ^= (unsigned __int64)&v8->ChildScbQueue;
goto LABEL_44;
}
LABEL_45:
KiRemoveSchedulingGroupQueue((_KPRCB *)v7, v8, 1u);
}
else
{
LABEL_44:
if( !Root )
goto LABEL_45;
}
LABEL_25:
*((_BYTE *)v8 + 112) &= ~4u;
LABEL_7:
if( v7 )
{
KiCheckForEffectivePriorityChange((struct KPRCB *)v7, (INT64)v8);
_InterlockedAnd64((volatile signed __int64 *)(v7 + 48), 0i64);
}
}
if( ++v6 >= (unsigned int)KeMaximumProcessors )
{
LOBYTE(CurrentIrql) = v27;
goto LABEL_11;
}
}
v11 = v9 | 0xC;
v8->Rank = Rank + 1;
*((_BYTE *)v8 + 112) = v11;
if( (v11 & 1) == 0 )
goto LABEL_7;
v19 = 1;
LABEL_34:
KiResortScbQueue((_KPRCB *)v7, v8, v19);
goto LABEL_7;
}
LABEL_11:
SchedulingGroup->Policy.AllFlags ^= (SchedulingGroup->Policy.AllFlags ^ (4 * v2)) & 4;
KiReadyDeferredReadyList(CurrentPrcb, &ReadyList);
if( (unsigned __int8)CurrentIrql >= 2u )
{
if( *((_QWORD *)CurrentPrcb + 2) && !*((_BYTE *)CurrentPrcb + 12586) )
KiRequestSoftwareInterrupt(CurrentPrcb, 2);
}
else
{
v12 = *((_QWORD *)CurrentPrcb + 1);
if( *((_QWORD *)CurrentPrcb + 2) )
{
KiAbProcessContextSwitch(*((_KTHREAD **)CurrentPrcb + 1), 0i64);
LODWORD(v24) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)CurrentPrcb + 12, 0i64) )
{
do
KeYieldProcessorEx(&v24);
while( *((_QWORD *)CurrentPrcb + 6) );
}
v17 = *((_QWORD *)CurrentPrcb + 2);
*((_QWORD *)CurrentPrcb + 2) = 0i64;
_disable();
KiEndThreadCycleAccumulation(CurrentPrcb, (_KTHREAD *)v12, 0i64);
_enable();
*((_QWORD *)CurrentPrcb + 1) = v17;
if( *(_BYTE *)(v17 + 388) == 1 )
{
v18 = (unsigned int)(*(_DWORD *)(v17 + 132) - *(_DWORD *)(v17 + 436));
*(_DWORD *)(v17 + 132) = v18 + KUSER_SHARED_DATA.TickCount.LowPart;
}
*(_BYTE *)(v17 + 388) = 2;
*(_BYTE *)(v12 + 643) = 32;
*(_BYTE *)(v12 + 390) = CurrentIrql;
KiQueueReadyThread((__int64)CurrentPrcb, v12, v18);
v13 = !KiSwapContext((PKTHREAD)v12, (PKTHREAD)v17);
}
else
{
v13 = (*(_DWORD *)(v12 + 116) & 0x40) == 0;
}
if( !v13 )
{
__writecr8(1ui64);
*(_DWORD *)(v12 + 116) &= ~0x40u;
KiDeliverApc(0, 0i64, 0i64);
}
__writecr8((unsigned __int8)CurrentIrql);
}
}Referenced by:
NtSetInformationJobObject