KeTransitionProcessorParkState
VOID __stdcall KeTransitionProcessorParkState(_KPRCB *CurrentPrcb){
int v1;
char v3;
char v4;
_KNODE *ParentNode;
unsigned __int64 GroupSetMember;
bool v7;
unsigned __int64 SharedReadyQueueMask;
_KSHARED_READY_QUEUE *SharedReadyQueue;
unsigned __int64 v10;
unsigned __int8 GroupIndex;
unsigned __int64 v12;
__int64 v13;
__int64 v14;
_ETHREAD *IdleThread;
int IdleState;
int v17;
UINT8 v18;
int v19;
unsigned __int8 v20;
_ETHREAD *NextThread;
char v22;
_ETHREAD *CurrentThread;
char v24;
bool v25;
_KPRCB *v26;
UINT64 v27;
UINT8 IsThreadRankNonZero;
char Priority;
INT64 v30;
UINT64 v31;
_KSHARED_READY_QUEUE *v32;
bool v33;
UINT64 SpinCount;
UINT64 v35;
INT64 v36[11];
char v37;
char v38;
v36[0] = 0i64;
v3 = 0;
v38 = 0;
v4 = 0;
v37 = 0;
ParentNode = CurrentPrcb->ParentNode;
GroupSetMember = CurrentPrcb->GroupSetMember;
if( !v1 )
{
v37 = 1;
v7 = (GroupSetMember & ParentNode->SoftParkedSet) != 0;
goto LABEL_10;
}
_m_prefetchw(&ParentNode->NonParkedSet);
if( (GroupSetMember & ParentNode->NonParkedSet) != 0 )
{
v3 = 1;
v4 = 1;
if( v1 == 2 )
{
v7 = 1;
goto LABEL_10;
}
v7 = 0;
}
else
{
v7 = 1;
}
v4 = v3;
if( v1 == 1 )
v3 = 1;
LABEL_10:
ExAcquireSpinLockExclusiveAtDpcLevel((INT64 *)&ParentNode->ParkLock);
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&CurrentPrcb->PrcbLock, 0i64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( CurrentPrcb->PrcbLock );
}
if( v4 || v37 )
{
_InterlockedXor64((volatile signed __int64 *)&ParentNode->NonParkedSet, GroupSetMember);
SharedReadyQueueMask = CurrentPrcb->SharedReadyQueueMask;
if( SharedReadyQueueMask )
{
SharedReadyQueue = CurrentPrcb->SharedReadyQueue;
v10 = SharedReadyQueueMask & ParentNode->NonParkedSet;
if( !v10 )
{
v38 = 1;
goto LABEL_25;
}
if( v10 == GroupSetMember )
{
(*(&KiProcessorBlock
+ (unsigned int)KiProcessorNumberToIndexMappingTable[64 * (unsigned __int64)CurrentPrcb->Group
+ SharedReadyQueue->ScanOwner]))->SharedQueueScanOwner = 0;
GroupIndex = CurrentPrcb->GroupIndex;
CurrentPrcb->SharedQueueScanOwner = 1;
LABEL_24:
SharedReadyQueue->ScanOwner = GroupIndex;
goto LABEL_25;
}
if( CurrentPrcb->SharedQueueScanOwner && v4 )
{
_BitScanReverse64(&v12, v10);
v13 = (unsigned int)v12 + (CurrentPrcb->Group << 6);
HIDWORD(SpinCount) = v12;
v14 = (__int64)*(&KiProcessorBlock + (unsigned int)KiProcessorNumberToIndexMappingTable[v13]);
CurrentPrcb->SharedQueueScanOwner = 0;
*(_DWORD *)(v14 + 33872) = 1;
GroupIndex = *(_BYTE *)(v14 + 209);
goto LABEL_24;
}
}
}
LABEL_25:
if( v7 )
_InterlockedXor64((volatile signed __int64 *)&ParentNode->SoftParkedSet, GroupSetMember);
ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)&ParentNode->ParkLock);
IdleThread = CurrentPrcb->IdleThread;
if( v37 )
{
IdleState = CurrentPrcb->IdleState;
if( (IdleState & 2) != 0 )
{
v17 = IdleState - 2;
if( v7 )
v17 = CurrentPrcb->IdleState - 6;
CurrentPrcb->IdleState = v17;
if( !v17 )
_InterlockedXor64((volatile signed __int64 *)ParentNode, GroupSetMember);
v18 = 0;
if( !v17 )
{
CurrentPrcb->IdleSchedule = 1;
v18 = 1;
}
KiUpdateThreadPriority(CurrentPrcb, &IdleThread->Tcb, 0i64, v18);
_InterlockedAnd64((volatile signed __int64 *)&CurrentPrcb->PrcbLock, 0i64);
if( v18 && KeHeteroSystem && !KeHeteroSystemVirtual )
KiSendHeteroRescheduleIntRequest(CurrentPrcb);
_InterlockedAdd16((volatile signed __int16 *)&KUSER_SHARED_DATA.UnparkedProcessorCount, 1u);
return;
}
LABEL_53:
__fastfail(0x21u);
}
if( !v4 && !v3 )
{
if( (CurrentPrcb->IdleState & 6) == 2 )
{
CurrentPrcb->IdleState += 4;
_InterlockedAnd64((volatile signed __int64 *)&CurrentPrcb->PrcbLock, 0i64);
return;
}
goto LABEL_53;
}
v19 = CurrentPrcb->IdleState;
if( v4 )
{
if( (v19 & 6) != 0 )
goto LABEL_53;
v19 += 2;
if( v19 == 2 )
_InterlockedXor64((volatile signed __int64 *)ParentNode, GroupSetMember);
}
v20 = v19 ^ 4;
if( !v7 )
v20 = v19;
NextThread = CurrentPrcb->NextThread;
CurrentPrcb->IdleState = v20;
if( !NextThread || NextThread == IdleThread )
{
v22 = 0;
}
else
{
CurrentPrcb->NextThread = 0i64;
_interlockedbittestandreset((volatile signed __int32 *)&NextThread->Tcb.116 + 1, 0xCu);
KiInsertDeferredReadyList((INT64)v36, (INT64)NextThread);
NextThread = 0i64;
v22 = 1;
}
CurrentThread = CurrentPrcb->CurrentThread;
v24 = 1;
if( CurrentThread == IdleThread )
{
if( v22 )
{
KiSetProcessorIdle(CurrentPrcb, 1ui64, 0i64);
v25 = v33;
goto LABEL_61;
}
goto LABEL_60;
}
if( NextThread )
{
LABEL_60:
v25 = 0;
goto LABEL_61;
}
if( (KeGetCurrentPrcb()->$A81AFC2514E605CDBADB8E27B49DE82B::_bf_0 & 0x10000) != 0 )
{
v24 = 0;
goto LABEL_60;
}
CurrentThread->Tcb.Preempted = 1;
_interlockedbittestandset((volatile signed __int32 *)&CurrentThread->Tcb.116 + 1, 0xCu);
CurrentPrcb->NextThread = IdleThread;
KiSetProcessorIdle(CurrentPrcb, 1ui64, 0i64);
v25 = (CurrentPrcb->DpcRequestSummary & 1) == 0;
LABEL_61:
if( v4 )
{
KiUpdateThreadPriority(CurrentPrcb, &IdleThread->Tcb, 127i64, 0);
if( v24 )
{
if( (IdleThread->Tcb.gap0[2] & 4) == 0
|| (IsThreadRankNonZero = KiIsThreadRankNonZero(&IdleThread->Tcb, CurrentPrcb, v26),
Priority = 1,
!IsThreadRankNonZero) )
{
Priority = IdleThread->Tcb.Priority;
}
*CurrentPrcb->PriorityState = Priority;
if( CurrentPrcb->SchedulerAssist )
{
v30 = (unsigned int)KiVpThreadSystemWorkPriority;
if( IdleThread != CurrentPrcb->IdleThread )
v30 = (unsigned int)Priority;
KiSetSchedulerAssistPriority((INT32 *)CurrentPrcb->SchedulerAssist, v30, 0);
}
}
if( KiGroupSchedulingEnabled )
KiGroupSchedulingGenerationEnd(CurrentPrcb, KUSER_SHARED_DATA.TickCountQuad, 1u);
KiFlushReadyLists(
CurrentPrcb->DispatcherReadyListHead,
(UINT64 *)&CurrentPrcb->ReadySummary,
(_SINGLE_LIST_ENTRY *)v36,
v27);
if( v38 )
{
v32 = CurrentPrcb->SharedReadyQueue;
LODWORD(v35) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)v32, 0i64) )
{
do
KeYieldProcessorEx(&v35);
while( v32->Lock );
}
KiFlushReadyLists(v32->ReadyListHead, (UINT64 *)&v32->ReadySummary, (_SINGLE_LIST_ENTRY *)v36, v31);
_InterlockedAnd64((volatile signed __int64 *)v32, 0i64);
}
}
_InterlockedAnd64((volatile signed __int64 *)&CurrentPrcb->PrcbLock, 0i64);
KiReadyDeferredReadyList(CurrentPrcb, (_SINGLE_LIST_ENTRY *)v36);
if( CurrentPrcb->NextThread && !CurrentPrcb->DpcRoutineActive )
KiRequestSoftwareInterrupt(CurrentPrcb, 2);
if( v4 )
_InterlockedDecrement16((volatile signed __int16 *)&KUSER_SHARED_DATA.UnparkedProcessorCount);
if( v25 )
KiRequestSoftwareInterrupt(CurrentPrcb, 2);
}Referenced by:
KiForceIdleParkUnparkProcessor
PpmParkReportParkedCore
PpmParkReportSoftParkChange
PpmParkReportUnparkedCore