KiHeteroChooseTargetProcessor
_KPRCB *__stdcall KiHeteroChooseTargetProcessor(
_KPRCB *CurrentPrcb,
_KTHREAD *Thread,
_GROUP_AFFINITY *Affinity,
UINT64 *Idle){
_KHETERO_CPU_POLICY v4;
unsigned __int64 Mask;
bool v7;
INT64 v8;
_KNODE *v9;
int v10;
unsigned __int64 IdleNonParkedCpuSet;
INT64 v12;
INT64 v13;
unsigned __int64 v14;
unsigned __int64 IdleSmtSet;
char v16;
UINT64 v17;
_KPRCB *v18;
INT64 v19;
__int64 v20;
unsigned __int64 v21;
unsigned __int64 v22;
int v23;
UINT64 v24;
__int64 v25;
__int64 v26;
UINT64 v27;
bool v28;
unsigned int BiasedProcessorIndex;
char v30;
unsigned __int64 v31;
int v32;
__int64 v33;
unsigned __int8 v34;
int v35;
unsigned __int64 v36;
__int64 v37;
unsigned __int8 v38;
char v39;
UINT64 v40;
UINT64 v41;
_KPRCB *v42;
__int64 v43;
char v44;
int v45;
unsigned __int64 v46;
unsigned __int64 v47;
unsigned __int64 v48;
unsigned __int64 v50;
UINT64 Affinitya;
UINT64 PreferredSetOut;
UINT64 SpinCount;
int v54;
UINT64 v55;
char v56[12];
INT64 v57;
bool CanSelectSoftParkedProcessor;
_KHETERO_CPU_POLICY v60;
v4 = *((unsigned __int8 *)Thread + 125);
Mask = Affinity->Mask;
Affinitya = 0i64;
*(_QWORD *)&v56[4] = 0i64;
PreferredSetOut = 0i64;
v50 = Mask;
v60 = v4;
if( (unsigned int)v4 >= KHeteroCpuPolicyDynamic )
{
v4 = KiConvertDynamicHeteroPolicy((_KTHREAD *)Thread, (_KHETERO_CPU_POLICY)Thread, CurrentPrcb);
v60 = v4;
}
v7 = 0;
CanSelectSoftParkedProcessor = 0;
v8 = (INT64)*(&KiProcessorBlock + *((unsigned int *)Thread + 147));
v57 = v8;
v9 = *(_KNODE **)(v8 + 192);
do
{
while( 1 )
{
v10 = KiGenerateHeteroSets(v9, Mask, v4, (UINT64 *)&v56[4], &PreferredSetOut, &Affinitya);
IdleNonParkedCpuSet = v9->IdleNonParkedCpuSet;
v12 = 0i64;
if( v7 && !IdleNonParkedCpuSet )
IdleNonParkedCpuSet = v9->IdleCpuSet & v9->SoftParkedSet;
v13 = Affinitya;
if( (IdleNonParkedCpuSet & Affinitya) == 0 && !v10 )
{
v13 = Affinitya;
if( (v9->NonParkedSet & Affinitya) == 0 )
{
v13 = Mask;
PreferredSetOut = Mask;
Affinitya = Mask;
*(_QWORD *)&v56[4] = Mask;
}
}
v14 = v13 & IdleNonParkedCpuSet;
if( v7 && !v14 )
v14 = Affinitya & v9->IdleCpuSet & v9->SoftParkedSet;
IdleSmtSet = v9->IdleSmtSet;
if( (KiVelocityFlags & 0x4000) == 0 || *((_BYTE *)Thread + 512) || (v16 = 1, (unsigned int)(v4 - 1) > 1) )
v16 = 0;
if( !v16 || (PreferredSetOut & IdleSmtSet) != 0 )
break;
v13 = PreferredSetOut & v9->NonParkedSet & v9->QosPreemptibleSet;
v17 = v9->NonPairedSmtSet & v13;
if( !v17 )
v17 = PreferredSetOut & v9->NonParkedSet & v9->QosPreemptibleSet;
if( !v17 )
goto LABEL_43;
v18 = KiSelectProcessorToPreempt((_KTHREAD *)Thread, (_KPRCB *)v8, v17, 0i64);
v19 = (INT64)v18;
if( (v17 & *((_QWORD *)v18 + 25)) == 0 )
goto LABEL_41;
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)(v19 + 48), 0i64) )
{
do
{
KeYieldProcessorEx(&SpinCount);
v18 = *(_KPRCB **)(v19 + 48);
}
while( v18 );
}
v8 = v57;
if( (*(_BYTE *)(v19 + 35) & 2) != 0 )
{
v12 = 0i64;
LABEL_38:
_InterlockedAnd64((volatile signed __int64 *)(v19 + 48), 0i64);
v13 = (INT64)KeGetCurrentPrcb();
if( *(_QWORD *)(v13 + 33976) && *(_BYTE *)(v13 + 32) <= 1u && !(_DWORD)v18 )
LABEL_41:
v12 = 0i64;
v4 = v60;
LABEL_43:
v7 = CanSelectSoftParkedProcessor;
break;
}
v12 = 0i64;
LOBYTE(v18) = *((_BYTE *)Thread + 195);
if( **(char **)(v19 + 56) >= (char)v18 )
goto LABEL_38;
v18 = *(_KPRCB **)(v19 + 16);
if( !v18 )
v18 = *(_KPRCB **)(v19 + 8);
LODWORD(v18) = (unsigned __int8)*((_DWORD *)v18 + 128) - 1;
LOBYTE(v18) = (unsigned int)v18 <= 1;
if( !(_BYTE)v18 )
goto LABEL_38;
if( (v9->IdleSmtSet & PreferredSetOut) == 0
&& ((v9->NonPairedSmtSet & *(_QWORD *)(v19 + 200)) != 0
|| (PreferredSetOut & v9->NonParkedSet & v9->QosPreemptibleSet & v9->NonPairedSmtSet) == 0) )
{
*(_DWORD *)Idle = (*(_BYTE *)(v19 + 35) & 1) == 0;
return(_KPRCB *)v19;
}
_InterlockedAnd64((volatile signed __int64 *)(v19 + 48), 0i64);
v7 = CanSelectSoftParkedProcessor;
LABEL_36:
v4 = v60;
Mask = v50;
}
if( v14 )
{
if( (*(_BYTE *)&v9->Flags & 0x20) != 0 )
{
if( KiIsQosGroupingActive()
&& (v21 = v14 & v20) != 0
&& (unsigned int)(unsigned __int8)*((_DWORD *)Thread + 128) - 1 <= 1 )
{
v14 = v21 & ~IdleSmtSet;
if( !v14 )
v14 = v21;
}
else
{
v22 = v14 & IdleSmtSet;
if( v22 )
v14 = v22;
}
}
v23 = v12;
v24 = *(_QWORD *)&v56[4] & v14;
if( (*(_QWORD *)&v56[4] & v14) == 0 )
{
v24 = v14 & PreferredSetOut;
if( (v14 & PreferredSetOut) == 0 )
goto LABEL_58;
v23 = 1;
}
v14 = v24;
LABEL_58:
if( KeHeteroSystemQos != (_DWORD)v12 )
{
v25 = (unsigned __int8)*((_DWORD *)Thread + 128);
v26 = *((_QWORD *)CurrentPrcb + 24);
if( (v14 & *(_QWORD *)(v26 + 8 * v25 + 304)) != 0 )
v14 &= *(_QWORD *)(v26 + 8 * v25 + 304);
}
v19 = v8;
if( (v14 & *(_QWORD *)(v8 + 200)) == 0 || v23 )
{
if( v23 )
{
v19 = v12;
v34 = v12;
if( v14 )
{
v35 = v9->Affinity.Group << 6;
do
{
_BitScanForward64(&v36, v14);
v54 = v36 & 0x3F;
v37 = (__int64)*(&KiProcessorBlock + (unsigned int)KiProcessorNumberToIndexMappingTable[v35 + v54]);
if( (unsigned int)(v60 - 3) <= 1 )
v38 = *(_BYTE *)(v37 + 33210);
else
v38 = *(_BYTE *)(v37 + 33209);
if( !v19 || v38 > v34 )
{
v19 = (INT64)*(&KiProcessorBlock + (unsigned int)KiProcessorNumberToIndexMappingTable[v35 + v54]);
v34 = v38;
}
v14 &= ~*(_QWORD *)(v37 + 200);
}
while( v14 );
v8 = v57;
}
}
else
{
v27 = v14 & *(_QWORD *)(v8 + 33880);
if( !v27 )
v27 = v14;
if( (KiHeteroSchedulerOptions & 1) != 0 )
v28 = (KiHeteroSchedulerOptions & 4) == 0;
else
v28 = (((KiDynamicHeteroCpuPolicyMask & 0x10) != 0) & _bittest(&KiVelocityFlags, 0xCu)) == 0;
if( v28 )
{
v30 = *(_BYTE *)(v8 + 209);
_BitScanForward64(&v31, __ROR8__(v27, v30));
v32 = ((_BYTE)v31 + v30) & 0x3F;
v33 = v32 + (*(unsigned __int8 *)(v8 + 208) << 6);
HIDWORD(SpinCount) = v32;
BiasedProcessorIndex = KiProcessorNumberToIndexMappingTable[v33];
}
else
{
BiasedProcessorIndex = KiFindBiasedProcessorIndex(
*(unsigned __int8 *)(v8 + 208),
(*((_QWORD *)Thread + 9) >> KiFavoredCoreCycleTimeBits)
+ *(unsigned __int8 *)(v8 + 209),
v27);
LODWORD(v12) = 0;
}
v19 = (INT64)*(&KiProcessorBlock + BiasedProcessorIndex);
}
}
LODWORD(v55) = v12;
*(_DWORD *)Idle = 1;
while( _interlockedbittestandset64((volatile signed __int32 *)(v19 + 48), 0i64) )
{
do
KeYieldProcessorEx(&v55);
while( *(_QWORD *)(v19 + 48) );
}
v39 = *(_BYTE *)(v19 + 35);
v7 = CanSelectSoftParkedProcessor;
if( !v39 || CanSelectSoftParkedProcessor && v39 == 6 )
return(_KPRCB *)v19;
_InterlockedAnd64((volatile signed __int64 *)(v19 + 48), 0i64);
goto LABEL_36;
}
if( v7 )
break;
Mask = v50;
CanSelectSoftParkedProcessor = KiCanSelectSoftParkedProcessor(v13, v8);
v7 = CanSelectSoftParkedProcessor;
}
while( CanSelectSoftParkedProcessor );
v40 = PreferredSetOut;
v41 = Affinitya;
if( PreferredSetOut == Affinitya )
v40 = 0i64;
v42 = KiSelectProcessorToPreempt((_KTHREAD *)Thread, (_KPRCB *)v8, Affinitya, v40);
v43 = (__int64)v42;
if( (v41 & *((_QWORD *)v42 + 25)) == 0 )
{
v44 = *((_BYTE *)v42 + 209);
v45 = *((unsigned __int8 *)v42 + 208);
_BitScanForward64(&v46, __ROR8__(v41, v44));
HIDWORD(v55) = ((_BYTE)v46 + v44) & 0x3F;
v43 = (__int64)*(&KiProcessorBlock + (unsigned int)KiProcessorNumberToIndexMappingTable[HIDWORD(v55) + (v45 << 6)]);
}
*(_DWORD *)v56 = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)(v43 + 48), 0i64) )
{
do
KeYieldProcessorEx((UINT64 *)v56);
while( *(_QWORD *)(v43 + 48) );
}
v47 = v9->IdleNonParkedCpuSet;
if( v7 )
{
v48 = v9->IdleCpuSet & v9->SoftParkedSet;
v47 |= v48;
}
if( (v47 & Affinitya) != 0 )
{
_InterlockedAnd64((volatile signed __int64 *)(v43 + 48), 0i64);
goto LABEL_36;
}
v28 = (*(_BYTE *)(v43 + 35) & 2) == 0;
*(_DWORD *)Idle = 0;
if( !v28 )
{
_InterlockedAnd64((volatile signed __int64 *)(v43 + 48), 0i64);
v43 = KiSelectCandidateProcessor(v43, (__int64)Thread, Affinitya);
if( (*(_BYTE *)(v43 + 35) & 1) == 0 )
*(_DWORD *)Idle = 1;
}
return(_KPRCB *)v43;
}Referenced by:
KiDeferredReadySingleThread