KiSetHeteroPolicyThread
_KHETERO_CPU_POLICY __stdcall KiSetHeteroPolicyThread(
_ETHREAD *Thread,
_KHETERO_CPU_POLICY NewPolicy,
UINT64 SetUserPolicy,
UINT64 Set){
int v4;
int v5;
unsigned __int8 CurrentIrql;
__int64 v9;
unsigned int v10;
_KHETERO_CPU_POLICY v11;
char v12;
bool v13;
_KHETERO_CPU_POLICY v14;
__int64 v15;
char v16;
unsigned __int64 v17;
char v18;
int v19;
int v20;
unsigned __int8 v21;
_KPRCB *v22;
__int64 v23;
unsigned int v24;
unsigned int v25;
UINT64 v26;
struct _KPRCB *CurrentPrcb;
ULONG_PTR v28;
__int64 v29;
__int64 v30;
bool v31;
_KPRCB *ControlPrcb;
_SINGLE_LIST_ENTRY ReadyList;
unsigned int a3;
unsigned int a3_4;
UINT64 v37;
UINT64 AvailableSetOut;
_KSHARED_READY_QUEUE *ControlReadyQueue;
UINT64 IdealSetOut;
UINT64 PreferredSetOut;
UINT64 SpinCount;
AvailableSetOut = 0i64;
v4 = Set;
IdealSetOut = 0i64;
v5 = SetUserPolicy;
ControlPrcb = 0i64;
PreferredSetOut = 0i64;
ReadyList.Next = 0i64;
ControlReadyQueue = 0i64;
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)Thread + 16, 0i64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( *((_QWORD *)Thread + 8) );
}
v9 = *((unsigned int *)Thread + 147);
v10 = *((_DWORD *)Thread + 49);
a3 = *((_DWORD *)Thread + 147);
a3_4 = v10;
if( v5 )
{
v11 = *((unsigned __int8 *)Thread + 125);
v12 = (*((_BYTE *)Thread + 126) ^ NewPolicy) & 0x7F;
v13 = ((v12 ^ *((_BYTE *)Thread + 126)) & 0x80u) != 0;
*((_BYTE *)Thread + 126) ^= v12;
if( v13 )
goto LABEL_8;
goto LABEL_7;
}
if( v4 )
{
LABEL_7:
v11 = NewPolicy;
goto LABEL_8;
}
v11 = *((_BYTE *)Thread + 126) & 0x7F;
*((_BYTE *)Thread + 126) &= ~0x80u;
LABEL_8:
if( v11 == KHeteroCpuPolicyDefault )
v11 = KiDefaultHeteroCpuPolicy;
if( !KeHeteroSystem )
{
v11 = KHeteroCpuPolicyAll;
*((_BYTE *)Thread + 126) &= ~0x80u;
}
if( *((unsigned __int8 *)Thread + 125) == v11 )
{
KiReleaseThreadLockSafe((INT64)Thread);
__writecr8(CurrentIrql);
}
else
{
v14 = v11;
v15 = (__int64)*(&KiProcessorBlock + v9);
if( v11 >= KHeteroCpuPolicyDynamic )
v14 = KiConvertDynamicHeteroPolicy((_KTHREAD *)Thread, NewPolicy, *(&KiProcessorBlock + v9));
KiGenerateHeteroSets(
*(_KNODE **)(v15 + 192),
*((_QWORD *)Thread + 72),
v14,
&IdealSetOut,
&PreferredSetOut,
&AvailableSetOut);
if( (IdealSetOut & *(_QWORD *)(v15 + 200)) == 0 )
{
v16 = *(_BYTE *)(v15 + 209);
_BitScanForward64(&v17, __ROR8__(IdealSetOut, v16));
v18 = v17 + v16;
LODWORD(v17) = *((_DWORD *)Thread + 29);
v19 = KiProcessorNumberToIndexMappingTable[64 * *(unsigned __int8 *)(v15 + 208) + (v18 & 0x3F)];
*((_DWORD *)Thread + 147) = v19;
if( (v17 & 8) == 0 )
*((_DWORD *)Thread + 49) = v19;
}
v20 = 0;
KiAcquireThreadStateLock(Thread, &ControlPrcb, &ControlReadyQueue);
v22 = ControlPrcb;
*((_BYTE *)Thread + 125) = v11;
if( v21 == 1 )
{
KiRemoveThreadFromAnyReadyQueue(v22, ControlReadyQueue, (_KTHREAD *)Thread, (unsigned int)*((char *)Thread + 195));
KiPrepareReadyThreadForRescheduling((_KTHREAD *)Thread, (unsigned int)*((char *)Thread + 195), &ReadyList);
}
else
{
v23 = (unsigned int)v21 - 2;
if( v21 == 2 )
{
if( (*((_QWORD *)v22 + 25) & AvailableSetOut) == 0 )
{
if( *((_BYTE *)Thread + 388) == 2 )
{
_interlockedbittestandset((volatile signed __int32 *)Thread + 30, 0xCu);
v22 = ControlPrcb;
if( !*((_QWORD *)ControlPrcb + 2) )
{
KiSelectNextThread(ControlPrcb, &ReadyList);
v20 = 1;
}
}
else
{
*((_BYTE *)Thread + 112) |= 8u;
v22 = ControlPrcb;
}
}
}
else if( v21 == 3 && (*((_QWORD *)v22 + 25) & AvailableSetOut) == 0 )
{
KiSelectNextThread(v22, &ReadyList);
KiInsertDeferredReadyList((INT64)&ReadyList, (INT64)Thread);
}
}
v24 = *((_DWORD *)Thread + 147);
v25 = *((_DWORD *)Thread + 49);
KiReleaseThreadStateLock(v23, (__int64)v22, (volatile signed __int64 *)ControlReadyQueue);
KiReleaseThreadLockSafe((INT64)Thread);
if( v20 )
{
v26 = *((unsigned int *)ControlPrcb + 9);
if( *((_DWORD *)KeGetPcr() + 105) != (_DWORD)v26 )
KiSendSoftwareInterrupt(v26, 2u);
}
if( (*(_DWORD *)(&PerfGlobalGroupMask + 2) & 0x8000000) != 0 )
{
EtwTraceIdealProcessor((INT64)Thread, 0x546u, a3, v24);
if( (*(_DWORD *)(&PerfGlobalGroupMask + 2) & 0x8000000) != 0 )
EtwTraceIdealProcessor((INT64)Thread, 0x547u, a3_4, v25);
}
CurrentPrcb = KeGetCurrentPrcb();
KiReadyDeferredReadyList(CurrentPrcb, &ReadyList);
if( CurrentIrql >= 2u )
{
if( *((_QWORD *)CurrentPrcb + 2) && !*((_BYTE *)CurrentPrcb + 12586) )
KiRequestSoftwareInterrupt(CurrentPrcb, 2);
}
else
{
v28 = *((_QWORD *)CurrentPrcb + 1);
if( *((_QWORD *)CurrentPrcb + 2) )
{
KiAbProcessContextSwitch(*((_KTHREAD **)CurrentPrcb + 1), 0i64);
LODWORD(v37) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)CurrentPrcb + 12, 0i64) )
{
do
KeYieldProcessorEx(&v37);
while( *((_QWORD *)CurrentPrcb + 6) );
}
v29 = *((_QWORD *)CurrentPrcb + 2);
*((_QWORD *)CurrentPrcb + 2) = 0i64;
_disable();
KiEndThreadCycleAccumulation(CurrentPrcb, (_KTHREAD *)v28, 0i64);
_enable();
*((_QWORD *)CurrentPrcb + 1) = v29;
if( *(_BYTE *)(v29 + 388) == 1 )
{
v30 = (unsigned int)(*(_DWORD *)(v29 + 132) - *(_DWORD *)(v29 + 436));
*(_DWORD *)(v29 + 132) = v30 + KUSER_SHARED_DATA.TickCount.LowPart;
}
*(_BYTE *)(v29 + 388) = 2;
*(_BYTE *)(v28 + 643) = 32;
*(_BYTE *)(v28 + 390) = CurrentIrql;
KiQueueReadyThread((__int64)CurrentPrcb, v28, v30);
v31 = !KiSwapContext((PKTHREAD)v28, (PKTHREAD)v29);
}
else
{
v31 = (*(_DWORD *)(v28 + 116) & 0x40) == 0;
}
if( !v31 )
{
__writecr8(1ui64);
*(_DWORD *)(v28 + 116) &= ~0x40u;
KiDeliverApc(0, 0i64, 0i64);
}
__writecr8(CurrentIrql);
}
}
return v11;
}Referenced by:
KeSetHeteroCpuPolicyThread
KeSetUserHeteroCpuPolicyThread
PopUpdateSingleThreadHeteroPolicies