KiHeteroChooseTargetProcessor
_KPRCB *__stdcall KiHeteroChooseTargetProcessor(
_KPRCB *CurrentPrcb,
_ETHREAD *Thread,
_GROUP_AFFINITY *Affinity,
UINT64 *Idle){
_KHETERO_CPU_POLICY SystemHeteroCpuPolicy;
unsigned __int64 Mask;
bool v7;
_KPRCB *v8;
_KNODE *ParentNode;
int v10;
unsigned __int64 IdleNonParkedCpuSet;
_KPRCB *v12;
__int64 v13;
unsigned __int64 v14;
unsigned __int64 IdleSmtSet;
char v16;
UINT64 v17;
_KPRCB *PrcbLock;
_KPRCB *v19;
__int64 v20;
unsigned __int64 v21;
unsigned __int64 v22;
int v23;
UINT64 v24;
__int64 ThreadFlags2;
_KNODE *v26;
UINT64 v27;
bool v28;
unsigned int BiasedProcessorIndex;
char GroupIndex;
unsigned __int64 v31;
int v32;
__int64 v33;
unsigned __int8 v34;
int v35;
unsigned __int64 v36;
__int64 v37;
unsigned __int8 v38;
unsigned __int8 IdleState;
UINT64 v40;
UINT64 v41;
_KPRCB *v42;
_KPRCB *v43;
char v44;
int Group;
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];
_KPRCB *v57;
bool CanSelectSoftParkedProcessor;
_KHETERO_CPU_POLICY v60;
SystemHeteroCpuPolicy = Thread->Tcb.SystemHeteroCpuPolicy;
Mask = Affinity->Mask;
Affinitya = 0i64;
*(_QWORD *)&v56[4] = 0i64;
PreferredSetOut = 0i64;
v50 = Mask;
v60 = SystemHeteroCpuPolicy;
if( (unsigned int)SystemHeteroCpuPolicy >= KHeteroCpuPolicyDynamic )
{
SystemHeteroCpuPolicy = KiConvertDynamicHeteroPolicy(Thread, (_KHETERO_CPU_POLICY)Thread, CurrentPrcb);
v60 = SystemHeteroCpuPolicy;
}
v7 = 0;
CanSelectSoftParkedProcessor = 0;
v8 = *(&KiProcessorBlock + Thread->Tcb.IdealProcessor);
v57 = v8;
ParentNode = v8->ParentNode;
do
{
while( 1 )
{
KiGenerateHeteroSets(ParentNode, Mask, SystemHeteroCpuPolicy, (UINT64 *)&v56[4], &PreferredSetOut, &Affinitya);
IdleNonParkedCpuSet = ParentNode->IdleNonParkedCpuSet;
v12 = 0i64;
if( v7 && !IdleNonParkedCpuSet )
IdleNonParkedCpuSet = ParentNode->IdleCpuSet & ParentNode->SoftParkedSet;
v13 = Affinitya;
if( (IdleNonParkedCpuSet & Affinitya) == 0 && !v10 )
{
v13 = Affinitya;
if( (ParentNode->NonParkedSet & Affinitya) == 0 )
{
v13 = Mask;
PreferredSetOut = Mask;
Affinitya = Mask;
*(_QWORD *)&v56[4] = Mask;
}
}
v14 = v13 & IdleNonParkedCpuSet;
if( v7 && !v14 )
v14 = Affinitya & ParentNode->IdleCpuSet & ParentNode->SoftParkedSet;
IdleSmtSet = ParentNode->IdleSmtSet;
if( (KiVelocityFlags & 0x4000) == 0
|| LOBYTE(Thread->Tcb.ThreadFlags2)
|| (v16 = 1, (unsigned int)(SystemHeteroCpuPolicy - 1) > 1) )
{
v16 = 0;
}
if( !v16 || (PreferredSetOut & IdleSmtSet) != 0 )
break;
v13 = PreferredSetOut & ParentNode->NonParkedSet & ParentNode->QosPreemptibleSet;
v17 = ParentNode->NonPairedSmtSet & v13;
if( !v17 )
v17 = PreferredSetOut & ParentNode->NonParkedSet & ParentNode->QosPreemptibleSet;
if( !v17 )
goto LABEL_43;
PrcbLock = KiSelectProcessorToPreempt(&Thread->Tcb, v8, v17, 0i64);
v19 = PrcbLock;
if( (v17 & PrcbLock->GroupSetMember) == 0 )
goto LABEL_41;
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&v19->PrcbLock, 0i64) )
{
do
{
KeYieldProcessorEx(&SpinCount);
PrcbLock = (_KPRCB *)v19->PrcbLock;
}
while( PrcbLock );
}
v8 = v57;
if( (v19->IdleState & 2) != 0 )
{
v12 = 0i64;
LABEL_38:
_InterlockedAnd64((volatile signed __int64 *)&v19->PrcbLock, 0i64);
v13 = (__int64)KeGetCurrentPrcb();
if( *(_QWORD *)(v13 + 33976) && *(_BYTE *)(v13 + 32) <= 1u && !(_DWORD)PrcbLock )
LABEL_41:
v12 = 0i64;
SystemHeteroCpuPolicy = v60;
LABEL_43:
v7 = CanSelectSoftParkedProcessor;
break;
}
v12 = 0i64;
LOBYTE(PrcbLock) = Thread->Tcb.Priority;
if( *v19->PriorityState >= (char)PrcbLock )
goto LABEL_38;
PrcbLock = (_KPRCB *)v19->NextThread;
if( !PrcbLock )
PrcbLock = (_KPRCB *)v19->CurrentThread;
LODWORD(PrcbLock) = (unsigned __int8)LODWORD(PrcbLock->ProcessorState.ContextFrame.P3Home) - 1;
LOBYTE(PrcbLock) = (unsigned int)PrcbLock <= 1;
if( !(_BYTE)PrcbLock )
goto LABEL_38;
if( (ParentNode->IdleSmtSet & PreferredSetOut) == 0
&& ((ParentNode->NonPairedSmtSet & v19->GroupSetMember) != 0
|| (PreferredSetOut & ParentNode->NonParkedSet & ParentNode->QosPreemptibleSet & ParentNode->NonPairedSmtSet) == 0) )
{
*(_DWORD *)Idle = (v19->IdleState & 1) == 0;
return v19;
}
_InterlockedAnd64((volatile signed __int64 *)&v19->PrcbLock, 0i64);
v7 = CanSelectSoftParkedProcessor;
LABEL_36:
SystemHeteroCpuPolicy = v60;
Mask = v50;
}
if( v14 )
{
if( (ParentNode->Flags._bf_0 & 0x20) != 0 )
{
if( KiIsQosGroupingActive()
&& (v21 = v14 & v20) != 0
&& (unsigned int)(unsigned __int8)Thread->Tcb.ThreadFlags2 - 1 <= 1 )
{
v14 = v21 & ~IdleSmtSet;
if( !v14 )
v14 = v21;
}
else
{
v22 = v14 & IdleSmtSet;
if( v22 )
v14 = v22;
}
}
v23 = (int)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 )
{
ThreadFlags2 = (unsigned __int8)Thread->Tcb.ThreadFlags2;
v26 = CurrentPrcb->ParentNode;
if( (v14 & v26->PpmConfiguredQosSets[ThreadFlags2]) != 0 )
v14 &= v26->PpmConfiguredQosSets[ThreadFlags2];
}
v19 = v8;
if( (v14 & v8->GroupSetMember) == 0 || v23 )
{
if( v23 )
{
v19 = v12;
v34 = (unsigned __int8)v12;
if( v14 )
{
v35 = ParentNode->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 = *(&KiProcessorBlock + (unsigned int)KiProcessorNumberToIndexMappingTable[v35 + v54]);
v34 = v38;
}
v14 &= ~*(_QWORD *)(v37 + 200);
}
while( v14 );
v8 = v57;
}
}
else
{
v27 = v14 & v8->CoreProcessorSet;
if( !v27 )
v27 = v14;
if( (KiHeteroSchedulerOptions & 1) != 0 )
v28 = (KiHeteroSchedulerOptions & 4) == 0;
else
v28 = (((KiDynamicHeteroCpuPolicyMask & 0x10) != 0) & _bittest(&KiVelocityFlags, 0xCu)) == 0;
if( v28 )
{
GroupIndex = v8->GroupIndex;
_BitScanForward64(&v31, __ROR8__(v27, GroupIndex));
v32 = ((_BYTE)v31 + GroupIndex) & 0x3F;
v33 = v32 + (v8->Group << 6);
HIDWORD(SpinCount) = v32;
BiasedProcessorIndex = KiProcessorNumberToIndexMappingTable[v33];
}
else
{
BiasedProcessorIndex = KiFindBiasedProcessorIndex(
v8->Group,
(Thread->Tcb.CycleTime >> KiFavoredCoreCycleTimeBits) + v8->GroupIndex,
v27);
LODWORD(v12) = 0;
}
v19 = *(&KiProcessorBlock + BiasedProcessorIndex);
}
}
LODWORD(v55) = (_DWORD)v12;
*(_DWORD *)Idle = 1;
while( _interlockedbittestandset64((volatile signed __int32 *)&v19->PrcbLock, 0i64) )
{
do
KeYieldProcessorEx(&v55);
while( v19->PrcbLock );
}
IdleState = v19->IdleState;
v7 = CanSelectSoftParkedProcessor;
if( !IdleState || CanSelectSoftParkedProcessor && IdleState == 6 )
return v19;
_InterlockedAnd64((volatile signed __int64 *)&v19->PrcbLock, 0i64);
goto LABEL_36;
}
if( v7 )
break;
Mask = v50;
CanSelectSoftParkedProcessor = KiCanSelectSoftParkedProcessor(v13, (__int64)v8);
v7 = CanSelectSoftParkedProcessor;
}
while( CanSelectSoftParkedProcessor );
v40 = PreferredSetOut;
v41 = Affinitya;
if( PreferredSetOut == Affinitya )
v40 = 0i64;
v42 = KiSelectProcessorToPreempt(&Thread->Tcb, v8, Affinitya, v40);
v43 = v42;
if( (v41 & v42->GroupSetMember) == 0 )
{
v44 = v42->GroupIndex;
Group = v42->Group;
_BitScanForward64(&v46, __ROR8__(v41, v44));
HIDWORD(v55) = ((_BYTE)v46 + v44) & 0x3F;
v43 = *(&KiProcessorBlock + (unsigned int)KiProcessorNumberToIndexMappingTable[HIDWORD(v55) + (Group << 6)]);
}
*(_DWORD *)v56 = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&v43->PrcbLock, 0i64) )
{
do
KeYieldProcessorEx((UINT64 *)v56);
while( v43->PrcbLock );
}
v47 = ParentNode->IdleNonParkedCpuSet;
if( v7 )
{
v48 = ParentNode->IdleCpuSet & ParentNode->SoftParkedSet;
v47 |= v48;
}
if( (v47 & Affinitya) != 0 )
{
_InterlockedAnd64((volatile signed __int64 *)&v43->PrcbLock, 0i64);
goto LABEL_36;
}
v28 = (v43->IdleState & 2) == 0;
*(_DWORD *)Idle = 0;
if( !v28 )
{
_InterlockedAnd64((volatile signed __int64 *)&v43->PrcbLock, 0i64);
v43 = KiSelectCandidateProcessor(v43, &Thread->Tcb, Affinitya);
if( (v43->IdleState & 1) == 0 )
*(_DWORD *)Idle = 1;
}
return v43;
}Referenced by:
KiDeferredReadySingleThread