KiSelectReadyThread
_KTHREAD *__stdcall KiSelectReadyThread(INT64 LowPriority, _KPRCB *Prcb){
_KSHARED_READY_QUEUE *SharedReadyQueue;
unsigned int v4;
UINT8 *ShareRankNonZero;
int v6;
unsigned __int64 NonParkedSet;
unsigned __int8 IdleState;
_ETHREAD *p_Blink;
unsigned int ReadySummary;
UINT64 v11;
unsigned __int64 Lock;
int v13;
struct _KPRCB *CurrentPrcb;
unsigned int v16;
unsigned __int64 v17;
_LIST_ENTRY *v18;
_LIST_ENTRY *Flink;
unsigned int v20;
unsigned __int64 AvailableMask;
_ETHREAD **v22;
_ETHREAD **v23;
struct _KPRCB *v24;
_KSCHEDULING_GROUP *volatile SchedulingGroup;
_KSCB *v26;
_KSCB *v27;
int v28;
_LIST_ENTRY *v29;
int v30;
_DWORD *SchedulerAssist;
unsigned __int64 v32;
int v33;
unsigned int QueueIndex;
UINT64 SpinCount;
_LIST_ENTRY *v36;
SharedReadyQueue = Prcb->SharedReadyQueue;
v4 = 1 << LowPriority;
ShareRankNonZero = 0i64;
v6 = LowPriority;
NonParkedSet = Prcb->ParentNode->NonParkedSet;
IdleState = Prcb->IdleState;
v32 = NonParkedSet;
if( (IdleState & 2) != 0 && (NonParkedSet & Prcb->SharedReadyQueueMask) != 0 && IdleState != 7 )
SharedReadyQueue = 0i64;
while( 1 )
{
p_Blink = 0i64;
if( !KiForceIdleDisabled && (_DWORD)KiForceIdleState == 4 )
return &p_Blink->Tcb;
ReadySummary = Prcb->ReadySummary;
v33 = -2;
v11 = 0xFFFFFFFFi64;
QueueIndex = -1;
if( ReadySummary >= v4 )
{
_BitScanReverse((unsigned int *)&v11, ReadySummary);
QueueIndex = v11;
ReadySummary = 1 << v11;
}
if( SharedReadyQueue )
{
LODWORD(Lock) = SharedReadyQueue->ReadySummary;
if( (unsigned int)Lock >= v4 )
{
_BitScanReverse((unsigned int *)&v13, Lock);
v33 = v13;
}
else
{
v13 = -2;
}
v11 = QueueIndex;
if( v13 > (int)QueueIndex || v13 == QueueIndex && !_bittest(&Prcb->AffinitizedSelectionMask, QueueIndex) )
{
CurrentPrcb = KeGetCurrentPrcb();
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)SharedReadyQueue, 0i64) )
{
do
{
KeYieldProcessorEx(&SpinCount);
Lock = SharedReadyQueue->Lock;
}
while( SharedReadyQueue->Lock );
SchedulerAssist = CurrentPrcb->SchedulerAssist;
if( SchedulerAssist && CurrentPrcb->NestingLevel <= 1u )
{
LODWORD(Lock) = SchedulerAssist[6] + 1;
SchedulerAssist[6] = Lock;
}
}
v16 = SharedReadyQueue->ReadySummary;
v17 = v32;
LABEL_18:
ShareRankNonZero = 0i64;
p_Blink = 0i64;
if( v16 >= v4 && v16 >= ReadySummary )
{
_BitScanReverse((unsigned int *)&v11, v16);
v33 = v11;
v18 = &SharedReadyQueue->ReadyListHead[(int)v11];
v16 ^= 1 << v11;
Flink = v18->Flink;
v36 = v18->Flink;
while( 1 )
{
v20 = BYTE5(Flink[-6].Flink);
p_Blink = (_ETHREAD *)&Flink[-14].Blink;
if( v20 >= 5 )
{
v20 = KiConvertDynamicHeteroPolicy((_ETHREAD *)&Flink[-14].Blink, (_KHETERO_CPU_POLICY)Flink, Prcb);
Flink = v36;
v17 = v32;
}
AvailableMask = -1i64;
if( v20 )
{
AvailableMask = Prcb->ParentNode->HeteroSets[v20].AvailableMask;
Flink = v36;
}
if( (AvailableMask & Prcb->GroupSetMember) != 0 )
break;
Lock = AvailableMask & Prcb->SharedReadyQueueMask;
if( (Lock & v17) == 0 )
break;
Flink = Flink->Flink;
v36 = Flink;
if( Flink == v18 )
goto LABEL_18;
}
if( (*(&p_Blink->Tcb.MiscFlags + 1) & 0x400000) != 0 )
_InterlockedAnd((volatile signed __int32 *)p_Blink->Tcb.SchedulerAssist, 0xFFFBFFFF);
v22 = *(_ETHREAD ***)p_Blink->Tcb.gapD8;
v23 = *(_ETHREAD ***)&p_Blink->Tcb.gapD8[8];
if( v22[1] != (_ETHREAD *)p_Blink->Tcb.gapD8 || *v23 != (_ETHREAD *)p_Blink->Tcb.gapD8 )
__fastfail(3u);
*v23 = (_ETHREAD *)v22;
v22[1] = (_ETHREAD *)v23;
if( v23 == v22 )
SharedReadyQueue->ReadySummary ^= 1 << v33;
--SharedReadyQueue->ReadyThreadCount;
SharedReadyQueue->ReadyQueueExpectedRunTime -= p_Blink->LastExpectedRunTime;
LODWORD(Lock) = Prcb->Number;
ShareRankNonZero = 0i64;
p_Blink->Tcb._bf_0 = Lock;
}
_InterlockedAnd64((volatile signed __int64 *)SharedReadyQueue, 0i64);
v24 = KeGetCurrentPrcb();
if( v24->SchedulerAssist && v24->NestingLevel <= 1u && !(_DWORD)Lock )
ShareRankNonZero = 0i64;
if( p_Blink )
{
if( v33 == QueueIndex )
_bittestandset(&Prcb->AffinitizedSelectionMask, QueueIndex);
goto LABEL_37;
}
v11 = QueueIndex;
}
}
if( (int)v11 >= v6 )
{
v29 = Prcb->DispatcherReadyListHead[(int)v11].Flink;
p_Blink = (_ETHREAD *)&v29[-14].Blink;
KiRemoveThreadFromReadyQueue(Prcb, v29, v11);
if( (_DWORD)v11 == v30 )
_bittestandreset(&Prcb->AffinitizedSelectionMask, v11);
}
if( !p_Blink )
return &p_Blink->Tcb;
LABEL_37:
SchedulingGroup = p_Blink->Tcb.SchedulingGroup;
if( !SchedulingGroup )
return &p_Blink->Tcb;
v26 = (_KSCB *)((char *)SchedulingGroup + Prcb->ScbOffset);
if( !v26 )
return &p_Blink->Tcb;
KiGetThreadEffectiveRankNonZero(p_Blink, v26, (_KPRCB *)v11, 1u, ShareRankNonZero);
if( !v28 )
return &p_Blink->Tcb;
KiAddThreadToScbQueue(Prcb, v27, &p_Blink->Tcb, 0i64);
ShareRankNonZero = 0i64;
}
}Referenced by:
KiChooseLowestRankedThread
KiGroupSchedulingGenerationEnd
KiGroupSchedulingQuantumEnd
KiQuantumEnd
KiRemoveBoostThread
KiSearchForNewThread
KiSelectNextThread
KiSelectReadyThreadEx
KiSwapThread