KiQueueReadyThread
VOID __stdcall KiQueueReadyThread(_KPRCB *Prcb, _ETHREAD *Thread){
_KPRCB *v2;
unsigned __int64 CycleTime;
unsigned int Preempted;
_KSCHEDULING_GROUP *volatile SchedulingGroup;
_KSCHEDULING_GROUP *v8;
unsigned __int64 v9;
_KSCHEDULING_GROUP *volatile v10;
_KSCB *v11;
_BYTE *SchedulerAssist;
__int64 Priority;
unsigned __int64 SharedReadyQueueMask;
struct _KPRCB *CurrentPrcb;
_KSHARED_READY_QUEUE *SharedReadyQueue;
_LIST_ENTRY *v17;
_LIST_ENTRY *v18;
_LIST_ENTRY *v19;
__int64 v20;
_LIST_ENTRY *v21;
_KSCB *v22;
int v23;
__int16 v24;
_KSCB *v25;
_ETHREAD *NextThread;
_KSCB *v27;
int v28;
_LIST_ENTRY *v29;
_LIST_ENTRY *v30;
_LIST_ENTRY *Flink;
unsigned int ReadySummary;
__int64 ExpectedRunTime;
int IdealProcessor;
unsigned int v35;
unsigned __int64 v36;
_ETHREAD *v37;
int v38;
_DWORD *v39;
_LIST_ENTRY *Blink;
bool v41;
NTSTATUS GuestSchedulerAssistPriority;
_BYTE *v43;
_QWORD *v44;
_SINGLE_LIST_ENTRY ReadyList;
UINT8 ShareRankNonZero;
UINT64 SpinCount;
_KSCHEDULING_GROUP *volatile v48;
CycleTime = Thread->Tcb.CycleTime;
Preempted = Thread->Tcb.Preempted;
if( Thread->Tcb.AffinityVersion != KiCpuSetSequence && (Thread->Tcb._bf_0 & 8) == 0
|| CycleTime >= Thread->Tcb.QuantumTarget )
{
if( KiTryToAcquireThreadLock(&Thread->Tcb, 0i64) )
{
IdealProcessor = Thread->Tcb.IdealProcessor;
if( CycleTime >= Thread->Tcb.QuantumTarget )
{
v35 = KiComputeNewPriority(&Thread->Tcb, 1);
if( !(unsigned __int8)KiUpdateVPBackingThreadPriority(Thread) )
KiUpdateThreadPriority(0i64, &Thread->Tcb, v35, 0);
v36 = CycleTime + (unsigned int)Thread->Tcb.SchedulerApc.SpareByte1 * KiCyclesPerClockQuantum;
if( (*(&Thread->Tcb.MiscFlags + 1) & 0x20) != 0 )
_interlockedbittestandreset((volatile signed __int32 *)&Thread->Tcb.116 + 1, 5u);
Thread->Tcb.QuantumTarget = v36;
KiTryScheduleNextForegroundBoost(&Thread->Tcb);
Preempted = 0;
}
if( !(unsigned int)KiCheckThreadAffinity(&Thread->Tcb)
&& (unsigned int)KiComputeThreadAffinity(&v37->Tcb)
&& !(unsigned int)KiPrcbInGroupAffinity(Prcb, &Thread->Tcb.Affinity) )
{
_interlockedbittestandset((volatile signed __int32 *)&Thread->Tcb.116 + 1, 0xCu);
}
v38 = Thread->Tcb.IdealProcessor;
KiReleaseThreadLockSafe((INT64)Thread);
if( (xmmword_140CFB490 & 0x8000000) != 0 )
EtwTraceIdealProcessor((__int64)Thread, 0x546u, IdealProcessor, v38);
}
else
{
_interlockedbittestandset((volatile signed __int32 *)&Thread->Tcb.116 + 1, 0xCu);
}
}
SchedulingGroup = Thread->Tcb.SchedulingGroup;
v48 = SchedulingGroup;
v8 = SchedulingGroup;
if( SchedulingGroup )
{
v22 = (_KSCB *)((char *)SchedulingGroup + Prcb->ScbOffset);
if( v22 )
{
v23 = 0;
while( 1 )
{
if( (*((_BYTE *)v22 + 112) & 4) != 0 )
{
if( KiCheckMaxOverQuotaTransition(v22, v8) )
{
if( (*((_BYTE *)v22 + 112) & 1) != 0 )
KiRemoveSchedulingGroupQueue(Prcb, v22, 1u);
}
else if( v22->GenerationCycles >= v22->RankCycleTarget && (*((_BYTE *)v22 + 112) & 2) == 0 )
{
KiRecomputeGroupSchedulingRank(v8, v22, Prcb);
}
}
else
{
KiComputeGroupSchedulingRank(v8, Prcb, v22);
}
v23 += v22->Rank;
v22 = v22->Parent;
if( !v22 )
break;
v8 = (_KSCHEDULING_GROUP *)((char *)v22 - Prcb->ScbOffset);
v48 = v8;
}
if( (*(&Thread->Tcb.MiscFlags + 1) & 0x200) == 0
&& Thread->Tcb.Priority < 16
&& KiShouldPreemptionBeDeferred(&Thread->Tcb)
&& v23
&& (v24 & 0xC00) == 0 )
{
_interlockedbittestandset((volatile signed __int32 *)&Thread->Tcb.116 + 1, 0xBu);
}
}
}
v9 = 0i64;
if( Thread->Tcb.Priority >= KiRebalanceMinPriority || (Prcb->IdleState & 2) != 0 )
{
v10 = Thread->Tcb.SchedulingGroup;
if( !v10 || (v25 = (_KSCB *)((char *)v10 + Prcb->ScbOffset)) == 0i64 || !KiCheckForMaxOverQuotaScb(v25) )
v9 = Thread->Tcb.Affinity.Mask & Prcb->ParentNode->IdleNonParkedCpuSet;
}
if( (*(&Thread->Tcb.MiscFlags + 1) & 0x1000) == 0 && !v9 )
{
Thread->Tcb.Preempted = 0;
Thread->Tcb.WaitBlock[2].SpareLong = KUSER_SHARED_DATA.TickCount.LowPart;
v11 = (_KSCB *)Thread->Tcb.SchedulingGroup;
if( v11 )
v11 = (_KSCB *)((char *)v11 + Prcb->ScbOffset);
SchedulerAssist = Prcb->SchedulerAssist;
if( SchedulerAssist )
SchedulerAssist[16] = 0;
Thread->Tcb.WaitBlockFill6[68] = 1;
ShareRankNonZero = 0;
if( v11 )
{
if( (*(&Thread->Tcb.MiscFlags + 1) & 0xC00) == 0 )
{
KiGetThreadEffectiveRankNonZero(Thread, v11, v2, 0, &ShareRankNonZero);
if( v28 )
{
KiAddThreadToScbQueue(Prcb, v27, &Thread->Tcb, Preempted);
goto LABEL_25;
}
}
}
Priority = Thread->Tcb.Priority;
if( (*(&Thread->Tcb.MiscFlags + 1) & 0x400000) != 0 )
{
_InterlockedOr((volatile signed __int32 *)Thread->Tcb.SchedulerAssist, 0x40000u);
if( (*(&Thread->Tcb.MiscFlags + 1) & 0x400000) != 0 )
{
v41 = 0;
GuestSchedulerAssistPriority = KiReadGuestSchedulerAssistPriority((INT64)Thread);
if( GuestSchedulerAssistPriority >= 16 )
GuestSchedulerAssistPriority = 15;
if( GuestSchedulerAssistPriority != Thread->Tcb.SchedulerAssistPriorityFloor )
{
KxAcquireSpinLock(&KiUpdateVpThreadPriorityLock);
v43 = Thread->Tcb.gap3F0;
if( *(_QWORD *)Thread->Tcb.gap3F0 == 1i64 )
{
v44 = (_QWORD *)qword_140C31CE8;
v41 = KiUpdateVpThreadPriorityListHead == (_QWORD)&KiUpdateVpThreadPriorityListHead;
if( *(__int64 **)qword_140C31CE8 != &KiUpdateVpThreadPriorityListHead )
goto LABEL_95;
*(_QWORD *)v43 = &KiUpdateVpThreadPriorityListHead;
*(_QWORD *)&Thread->Tcb.gap3F0[8] = v44;
*v44 = v43;
qword_140C31CE8 = (__int64)Thread->Tcb.gap3F0;
}
KxReleaseSpinLock(&KiUpdateVpThreadPriorityLock);
if( v41 )
KeInsertQueueDpc((UINT64)&KiUpdateVpThreadPriorityDpc, 0i64, 0i64);
}
}
}
SharedReadyQueueMask = Prcb->SharedReadyQueueMask;
if( (*(&Thread->Tcb.MiscFlags + 1) & 0x2000) == 0
|| !SharedReadyQueueMask
|| (SharedReadyQueueMask & Thread->Tcb.Affinity.Mask) != SharedReadyQueueMask
|| ShareRankNonZero )
{
v29 = (_LIST_ENTRY *)Thread->Tcb.gapD8;
v30 = &Prcb->DispatcherReadyListHead[Priority];
if( Preempted )
{
Flink = v30->Flink;
if( v30->Flink->Blink != v30 )
goto LABEL_95;
v29->Flink = Flink;
*(_QWORD *)&Thread->Tcb.gapD8[8] = v30;
Flink->Blink = v29;
v30->Flink = v29;
_bittestandset(&Prcb->AffinitizedSelectionMask, Priority);
}
else
{
Blink = v30->Blink;
if( Blink->Flink != v30 )
goto LABEL_95;
v29->Flink = v30;
*(_QWORD *)&Thread->Tcb.gapD8[8] = Blink;
Blink->Flink = v29;
v30->Blink = v29;
}
ReadySummary = Prcb->ReadySummary;
++Prcb->ReadyThreadCount;
Prcb->ReadySummary = ReadySummary | (1 << Priority);
ExpectedRunTime = Thread->Tcb.ExpectedRunTime;
Thread->LastExpectedRunTime = ExpectedRunTime;
Prcb->ReadyQueueExpectedRunTime += ExpectedRunTime;
goto LABEL_25;
}
CurrentPrcb = KeGetCurrentPrcb();
SharedReadyQueue = Prcb->SharedReadyQueue;
v17 = &SharedReadyQueue->ReadyListHead[Priority];
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)SharedReadyQueue, 0i64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( SharedReadyQueue->Lock );
v39 = CurrentPrcb->SchedulerAssist;
if( v39 )
{
if( CurrentPrcb->NestingLevel <= 1u )
++v39[6];
}
}
v18 = (_LIST_ENTRY *)Thread->Tcb.gapD8;
if( Preempted )
{
v19 = v17->Flink;
if( v17->Flink->Blink == v17 )
{
v18->Flink = v19;
*(_QWORD *)&Thread->Tcb.gapD8[8] = v17;
v19->Blink = v18;
v17->Flink = v18;
_bittestandreset(&Prcb->AffinitizedSelectionMask, Priority);
LABEL_24:
SharedReadyQueue->ReadySummary |= 1 << Priority;
Thread->Tcb._bf_0 |= 0x80000000;
++SharedReadyQueue->ReadyThreadCount;
v20 = Thread->Tcb.ExpectedRunTime;
Thread->LastExpectedRunTime = v20;
SharedReadyQueue->ReadyQueueExpectedRunTime += v20;
_InterlockedAnd64((volatile signed __int64 *)SharedReadyQueue, 0i64);
LABEL_25:
_InterlockedAnd64((volatile signed __int64 *)&Prcb->PrcbLock, 0i64);
return;
}
}
else
{
v21 = v17->Blink;
if( v21->Flink == v17 )
{
v18->Flink = v17;
*(_QWORD *)&Thread->Tcb.gapD8[8] = v21;
v21->Flink = v18;
v17->Blink = v18;
goto LABEL_24;
}
}
LABEL_95:
__fastfail(3u);
}
NextThread = Prcb->NextThread;
KiEnterDeferredReadyState((INT64)Thread);
_InterlockedAnd64((volatile signed __int64 *)&Prcb->PrcbLock, 0i64);
_interlockedbittestandreset((volatile signed __int32 *)&Thread->Tcb.116 + 1, 0xCu);
Thread->Tcb.Preempted = Preempted;
ReadyList.Next = (_SINGLE_LIST_ENTRY *)Thread->Tcb.gapD8;
*(_QWORD *)Thread->Tcb.gapD8 = 0i64;
KiReadyDeferredReadyList(Prcb, &ReadyList);
if( !NextThread && Prcb->CurrentThread != Prcb->IdleThread && Prcb->NextThread )
KiRequestSoftwareInterrupt(Prcb, 2);
}Referenced by:
KeBoostPriorityThread
KeCpuSetReportParkedProcessors
KeDelayExecutionThread
KeRecomputeCpuSetAffinityProcess
KeRemoveQueueEx
KeSetAffinityThread
KeSetBasePriorityThread
KeSetCpuSetsProcess
KeSetLegacyAffinityThread
KeSetSchedulingGroupRankBias
KeSetSelectedCpuSetsThread
KeSetThreadSchedulerAssist
KeUpdateThreadCpuSets
KeYieldExecution
KiAbForceProcessLockEntry
KiAbThreadUnboostCpuPriority
KiCheckForThreadDispatch
KiExitDispatcher
KiProcessDeferredReadyList
KiQuantumEnd
KiReadyOutSwappedThreads
KiSchedulerApc
KiSetHeteroPolicyThread
KxDispatchInterrupt
PsImpersonateContainerOfThread