KiChooseTargetProcessor
_KPRCB *__stdcall KiChooseTargetProcessor(
_KPRCB *CurrentPrcb,
_ETHREAD *Thread,
_GROUP_AFFINITY *Affinity,
UINT64 *Idle){
CHAR v4;
unsigned __int64 Mask;
bool v6;
unsigned __int16 Group;
_KPRCB *v9;
__int64 NextProcessor;
_KPRCB *v11;
_KPRCB *v12;
_KPRCB *v13;
__int64 IdealProcessor;
_KNODE *ParentNode;
__int64 v16;
_KNODE *v17;
unsigned __int64 IdleNonParkedCpuSet;
UINT64 v19;
UINT64 v20;
struct _KPRCB *v21;
unsigned __int8 IdleState;
UINT64 v24;
UINT64 v25;
UINT64 v26;
char v27;
unsigned __int64 v28;
int v29;
__int64 v30;
unsigned __int64 v31;
unsigned __int64 v32;
_KNODE *v33;
unsigned __int64 v34;
__int64 v35;
unsigned int v36;
UINT64 v37;
unsigned __int8 *v38;
__int64 v39;
size_t v40;
char *v41;
char v42;
unsigned int v43;
char Priority;
int v45;
__int64 v46;
__int64 v47;
struct _KPRCB *v48;
_QWORD *v49;
__int64 v50;
__int64 v51;
UINT64 *v52;
_DWORD *SchedulerAssist;
struct _KPRCB *v54;
_DWORD *v55;
unsigned int NextNode;
__int64 v57;
_DWORD *v58;
struct _KPRCB *v59;
_DWORD *v60;
char RankBiasedIdleSmtSet;
bool v62;
unsigned int v63;
unsigned int v64;
char *v65;
__int64 v66;
int v67;
__int64 v68;
_KPRCB *v69;
unsigned __int16 v70;
bool v71;
UINT64 AffinityMask;
UINT64 IdleCandidateSet;
_KNODE *PreferredNode;
UINT64 LookupIndex;
unsigned __int64 v77;
int v78;
UINT64 SpinCount;
__int128 v80;
__int64 v81;
__int64 v82;
UINT64 *v83;
char v84[64];
CHAR v85;
v4 = v85;
Mask = Affinity->Mask;
v6 = 0;
v83 = Idle;
Group = Affinity->Group;
v9 = CurrentPrcb;
v70 = Group;
LODWORD(LookupIndex) = 0;
v80 = 0i64;
AffinityMask = Mask;
v71 = 0;
while( 1 )
{
while( 1 )
{
while( 1 )
{
NextProcessor = Thread->Tcb.NextProcessor;
LODWORD(NextProcessor) = NextProcessor & 0x7FFFFFFF;
WORD4(v80) = Group;
v11 = *(&KiProcessorBlock + NextProcessor);
if( Group == v9->Group )
{
LODWORD(v12) = KiTryLocalThreadSchedule((INT64)v9, (INT64)v11, (INT64)Thread, Mask, v4, v6);
v13 = v12;
if( v12 )
goto LABEL_18;
Mask = AffinityMask;
v9 = CurrentPrcb;
}
IdealProcessor = Thread->Tcb.IdealProcessor;
v13 = 0i64;
ParentNode = v11->ParentNode;
PreferredNode = ParentNode;
v16 = (__int64)*(&KiProcessorBlock + IdealProcessor);
*(_QWORD *)&v80 = Mask;
v17 = *(_KNODE **)(v16 + 192);
if( ParentNode == v17 )
v13 = v11;
IdleNonParkedCpuSet = v17->IdleNonParkedCpuSet;
v19 = Mask & v17->IdleNonParkedCpuSet;
IdleCandidateSet = v19;
v20 = v19;
if( v71 )
{
if( v19 )
goto LABEL_9;
IdleNonParkedCpuSet = v17->IdleCpuSet & v17->SoftParkedSet;
v19 = Mask & IdleNonParkedCpuSet;
IdleCandidateSet = Mask & IdleNonParkedCpuSet;
v20 = Mask & IdleNonParkedCpuSet;
}
if( !v20 )
goto LABEL_34;
LABEL_9:
if( (v17->Flags._bf_0 & 0x20) == 0 )
goto LABEL_14;
if( v4 )
{
RankBiasedIdleSmtSet = KiFindRankBiasedIdleSmtSet(v16, &IdleCandidateSet);
Mask = AffinityMask;
ParentNode = PreferredNode;
if( RankBiasedIdleSmtSet )
{
v19 = IdleCandidateSet;
goto LABEL_14;
}
v9 = CurrentPrcb;
}
v19 = IdleCandidateSet;
if( (IdleCandidateSet & v17->IdleSmtSet) != 0 )
{
if( v4
&& (unsigned int)((0x101010101010101i64
* ((((IdleNonParkedCpuSet - ((IdleNonParkedCpuSet >> 1) & 0x5555555555555555i64)) & 0x3333333333333333i64)
+ (((IdleNonParkedCpuSet - ((IdleNonParkedCpuSet >> 1) & 0x5555555555555555i64)) >> 2) & 0x3333333333333333i64)
+ ((((IdleNonParkedCpuSet - ((IdleNonParkedCpuSet >> 1) & 0x5555555555555555i64)) & 0x3333333333333333i64)
+ (((IdleNonParkedCpuSet - ((IdleNonParkedCpuSet >> 1) & 0x5555555555555555i64)) >> 2) & 0x3333333333333333i64)) >> 4)) & 0xF0F0F0F0F0F0F0Fi64)) >> 32) >> 24 < KiPerfIsoEnabled )
{
goto LABEL_34;
}
v19 = IdleCandidateSet & v17->IdleSmtSet;
IdleCandidateSet = v19;
}
else
{
if( v4 )
goto LABEL_34;
if( v9->ParentNode == v17 )
{
KiReduceByEffectiveIdleSmtSet(v9, &IdleCandidateSet);
v19 = IdleCandidateSet;
Mask = AffinityMask;
ParentNode = PreferredNode;
}
}
LABEL_14:
if( (v19 & *(_QWORD *)(v16 + 200)) != 0 )
{
v13 = (_KPRCB *)v16;
}
else if( !v13 || (v19 & v13->GroupSetMember) == 0 )
{
v24 = v19 & *(_QWORD *)(v16 + 33880);
if( v24 )
{
v19 &= *(_QWORD *)(v16 + 33880);
IdleCandidateSet = v24;
}
else if( v13 && (v25 = v19 & v13->CoreProcessorSet) != 0 )
{
v19 &= v13->CoreProcessorSet;
IdleCandidateSet = v25;
}
else if( (KiCacheAwareScheduling & 1) != 0 )
{
v26 = v19 & *(_QWORD *)(v16 + 33896);
if( v26 )
{
v19 &= *(_QWORD *)(v16 + 33896);
IdleCandidateSet = v26;
}
else if( v13 )
{
if( (v19 & v13->LLCMask) != 0 )
v19 &= v13->LLCMask;
IdleCandidateSet = v19;
}
}
v27 = *(_BYTE *)(v16 + 209);
_BitScanForward64(&v28, __ROR8__(v19, v27));
v29 = ((_BYTE)v28 + v27) & 0x3F;
v30 = v29 + (*(unsigned __int8 *)(v16 + 208) << 6);
v78 = v29;
v13 = *(&KiProcessorBlock + (unsigned int)KiProcessorNumberToIndexMappingTable[v30]);
}
if( v13 )
goto LABEL_17;
LABEL_34:
v77 = v17->Affinity.Mask;
v31 = v77;
v32 = Mask & ~v77;
*(_QWORD *)&v80 = v32;
if( ParentNode == v17 || !v32 || ParentNode->Affinity.Group != v70 )
break;
v13 = KiSelectIdleProcessor(Mask, CurrentPrcb, PreferredNode, v11);
if( !v13 )
{
v31 = v77;
Mask = AffinityMask;
ParentNode = PreferredNode;
break;
}
LABEL_17:
v6 = v71;
LABEL_18:
v21 = KeGetCurrentPrcb();
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&v13->PrcbLock, 0i64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( v13->PrcbLock );
SchedulerAssist = v21->SchedulerAssist;
if( SchedulerAssist && v21->NestingLevel <= 1u )
++SchedulerAssist[6];
}
IdleState = v13->IdleState;
if( !IdleState || v6 && IdleState == 6 )
{
*(_DWORD *)v83 = 1;
return v13;
}
_InterlockedAnd64((volatile signed __int64 *)&v13->PrcbLock, 0i64);
v54 = KeGetCurrentPrcb();
Mask = AffinityMask;
v9 = CurrentPrcb;
Group = v70;
v55 = v54->SchedulerAssist;
if( v55 && v54->NestingLevel <= 1u )
{
v62 = v55[6]-- == 1;
LABEL_95:
if( v62 )
{
v9 = CurrentPrcb;
Group = v70;
goto LABEL_97;
}
}
}
if( v70 == ParentNode->Affinity.Group )
v32 = Mask & ~(v31 | ParentNode->Affinity.Mask);
v9 = CurrentPrcb;
*(_QWORD *)&v80 = v32;
v33 = CurrentPrcb->ParentNode;
v77 = (unsigned __int64)v33;
if( v33 != v17 && v33 != ParentNode && v32 )
{
if( v70 != v33->Affinity.Group )
{
LABEL_94:
v34 = v32;
goto LABEL_40;
}
v13 = KiSelectIdleProcessor(Mask, CurrentPrcb, v33, CurrentPrcb);
if( !v13 )
{
v33 = (_KNODE *)v77;
v9 = CurrentPrcb;
ParentNode = PreferredNode;
goto LABEL_38;
}
goto LABEL_17;
}
LABEL_38:
if( v70 != v33->Affinity.Group )
goto LABEL_94;
v34 = v32 & ~v33->Affinity.Mask;
LABEL_40:
v35 = (1i64 << LOBYTE(v17->NodeNumber)) | (1i64 << v33->Affinity.Reserved[0]);
LODWORD(LookupIndex) = 0;
v36 = v17->SiblingMask & ~(v35 | (1 << ParentNode->Affinity.Reserved[0]));
LABEL_41:
*(_QWORD *)&v80 = v34;
while( v34 )
{
NextNode = MmGetNextNode(v17->Affinity.Reserved[0], &LookupIndex);
if( NextNode == -1 )
break;
v57 = v36;
if( _bittest64(&v57, NextNode) )
{
v77 = KeNodeBlock[NextNode];
v13 = KiSelectIdleProcessor(AffinityMask, v9, (_KNODE *)v77, 0i64);
if( v13 )
{
v4 = v85;
goto LABEL_17;
}
v9 = CurrentPrcb;
v34 &= ~*(_QWORD *)(v77 + 136);
goto LABEL_41;
}
}
if( v71 )
break;
v6 = 0;
v81 = 0i64;
v82 = 0i64;
HIDWORD(LookupIndex) = 0;
v71 = 0;
if( KeSoftParkedQueueThreshold )
{
KeQueryReadyQueueStatsProcessor(v16, (_DWORD *)&LookupIndex + 1, &v81, (_DWORD *)&LookupIndex + 1, &v82);
v9 = CurrentPrcb;
v6 = v81 + v82 > (unsigned __int64)(unsigned int)KeSoftParkedQueueThreshold;
v71 = v6;
}
v4 = v85;
Group = v70;
if( !v6 )
break;
LABEL_97:
Mask = AffinityMask;
}
v37 = AffinityMask & *(_QWORD *)(v16 + 33856);
if( ((v37 - 1) & v37) == 0 )
goto LABEL_59;
v38 = *(unsigned __int8 **)(v16 + 33864);
v39 = v38[593];
v40 = v38[592];
v41 = &v84[v39];
v42 = v38[593];
memmove(&v84[v39], v38 + 528, v40);
v43 = v39 + v40;
Priority = Thread->Tcb.Priority;
v45 = -1;
v46 = *(_QWORD *)(*(_QWORD *)(v16 + 192) + 360i64);
if( (KiHeteroSchedulerOptions & 1) != 0 )
{
if( (KiHeteroSchedulerOptions & 2) == 0 )
goto LABEL_51;
}
else if( (KiVelocityFlags & 0x800) == 0 || !KeHeteroSystemQos )
{
goto LABEL_51;
}
if( (v46 & v37) != 0 )
{
v63 = (unsigned __int8)Thread->Tcb.ThreadFlags2 - 1;
LOBYTE(v63) = v63 <= 1;
if( (_BYTE)v63 )
{
v64 = v39;
if( (unsigned int)v39 >= v43 )
goto LABEL_57;
v65 = &v84[v39];
do
{
v66 = (1i64 << v64) & v46;
if( (v66 & v37) != 0 && *v65 < Priority )
{
Priority = *v65;
v45 = v64;
}
++v64;
++v65;
}
while( v64 < v43 );
v42 = v39;
if( v45 >= 0 )
{
LABEL_58:
v16 = (__int64)*(&KiProcessorBlock
+ (unsigned int)KiProcessorNumberToIndexMappingTable[64 * *(unsigned __int8 *)(v16 + 208) + v45]);
goto LABEL_59;
}
}
}
LABEL_51:
if( (unsigned int)v39 < v43 )
{
v47 = __ROL8__(1i64, v42);
do
{
if( (v47 & v37) != 0 && *v41 < Priority )
{
Priority = *v41;
v45 = v39;
}
LODWORD(v39) = v39 + 1;
v47 = __ROL8__(v47, 1);
++v41;
}
while( (unsigned int)v39 < v43 );
}
LABEL_57:
if( v45 >= 0 )
goto LABEL_58;
LABEL_59:
v48 = KeGetCurrentPrcb();
v49 = *(_QWORD **)(v16 + 192);
HIDWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)(v16 + 48), 0i64) )
{
do
KeYieldProcessorEx((UINT64 *)((char *)&SpinCount + 4));
while( *(_QWORD *)(v16 + 48) );
v58 = v48->SchedulerAssist;
if( v58 && v48->NestingLevel <= 1u )
{
v67 = v58[6] + 1;
v58[6] = v67;
}
}
v6 = v71;
if( v71 )
{
v68 = v49[3];
v50 = v68 & v49[11];
}
else
{
v50 = 0i64;
}
v4 = v85;
if( v85 )
break;
Mask = AffinityMask;
v51 = v50 | *v49;
if( (v51 & AffinityMask) == 0 )
break;
_InterlockedAnd64((volatile signed __int64 *)(v16 + 48), 0i64);
v59 = KeGetCurrentPrcb();
v9 = CurrentPrcb;
Group = v70;
v60 = v59->SchedulerAssist;
if( v60 && v59->NestingLevel <= 1u )
{
v62 = v60[6]-- == 1;
goto LABEL_95;
}
}
v52 = v83;
*(_DWORD *)v83 = 0;
if( (*(_BYTE *)(v16 + 35) & 2) != 0 )
{
_InterlockedAnd64((volatile signed __int64 *)(v16 + 48), 0i64);
v69 = KiSelectCandidateProcessor((_KPRCB *)v16, &Thread->Tcb, 0xFFFFFFFFFFFFFFFFui64);
v16 = (__int64)v69;
if( !v85 && (v69->IdleState & 1) == 0 )
*(_DWORD *)v52 = 1;
}
return(_KPRCB *)v16;
}Referenced by:
KiDeferredReadySingleThread