PoIdle
VOID __stdcall PoIdle(_KPRCB *Prcb){
unsigned __int16 v1;
_PPM_IDLE_STATES *IdleStates;
_PROC_IDLE_ACCOUNTING *IdleAccounting;
UINT64 v5;
_PPM_IDLE_STATES *v6;
unsigned __int64 IdleTimeLast;
__int64 ActualState;
char *v9;
unsigned __int64 *v10;
unsigned int v11;
__int64 v12;
unsigned int v13;
unsigned int v14;
unsigned int PlatformIdleStateIndex;
UINT64 TargetState;
_PPM_IDLE_STATES *v18;
unsigned __int16 v19;
unsigned __int8 InterruptsEnabled;
unsigned __int16 Count;
struct _KPRCB *CurrentPrcb;
_KNODE *ParentNode;
unsigned int v24;
NTSTATUS NextNode;
__int64 v26;
UINT64 *GlobalHintFloor;
UINT8 DeepSleepEnabled[3];
UINT64 SelectedProcessorState;
UINT64 EnterTime;
UINT64 LookupIndex;
UINT64 InterruptTime;
UINT64 DurationHint;
UINT8 SynchronizedTransition[8];
_KAFFINITY_EX Affinity;
v1 = 0;
DeepSleepEnabled[0] = 0;
EnterTime = 0i64;
InterruptTime = 0i64;
*(_QWORD *)SynchronizedTransition = 0i64;
SelectedProcessorState = 0i64;
memset(Affinity.Bitmap, 0i64, sizeof(Affinity.Bitmap));
if( *(_BYTE *)(2736i64 * *(&stru_140C23628 + 441) + *(&stru_140C00F40 + 365) + 189) )
return;
IdleStates = Prcb->PowerState.IdleStates;
IdleAccounting = Prcb->PowerState.IdleAccounting;
v5 = 0i64;
DurationHint = 0i64;
if( !IdleStates )
goto LABEL_56;
IdleStates->CoordinatedSelection.SelectedStates = 0;
v6 = Prcb->PowerState.IdleStates;
if( v6->UnaccountedTransition )
{
IdleTimeLast = Prcb->PowerState.IdleTimeLast;
Prcb->PowerState.IdleTimeLast = 0i64;
ActualState = v6->ActualState;
Prcb->PowerState.IdleTimeTotal += IdleTimeLast;
v9 = (char *)Prcb->PowerState.IdleAccounting + 1000 * ActualState;
*((_QWORD *)v9 + 5) += IdleTimeLast;
if( v6->PreviousCancelReason == 3 )
{
if( v6->PreviousStatus < 0 )
{
++*((_DWORD *)v9 + 13);
}
else
{
++*((_DWORD *)v9 + 14);
v10 = (unsigned __int64 *)&PpmIdleIntervalLimits;
v11 = 0;
while( IdleTimeLast >= *v10 )
{
if( IdleTimeLast < v10[3] )
{
++v11;
break;
}
v10 += 6;
v11 += 2;
if( v11 >= 0x1A )
goto LABEL_58;
}
if( v11 >= 0x1A )
{
LABEL_58:
++*((_DWORD *)v9 + 15);
goto LABEL_17;
}
v12 = 32i64 * v11;
*(_QWORD *)&v9[v12 + 208] += IdleTimeLast;
++*(_DWORD *)&v9[v12 + 232];
if( IdleTimeLast < *(_QWORD *)&v9[v12 + 216] )
*(_QWORD *)&v9[v12 + 216] = IdleTimeLast;
if( IdleTimeLast > *(_QWORD *)&v9[v12 + 224] )
*(_QWORD *)&v9[v12 + 224] = IdleTimeLast;
LABEL_17:
if( IdleTimeLast < *((_QWORD *)v9 + 8) )
*((_QWORD *)v9 + 8) = IdleTimeLast;
if( IdleTimeLast > *((_QWORD *)v9 + 9) )
*((_QWORD *)v9 + 9) = IdleTimeLast;
}
}
else
{
++*((_DWORD *)v9 + 12);
}
}
v6->PreviousStatus = 0;
v6->PreviousCancelReason = 3;
v6->UnaccountedTransition = 0;
IdleStates->UnaccountedTransition = 1;
*(_DWORD *)&Affinity.Count = 1310721;
memset(&Affinity.Reserved, 0i64, 0xA4u);
IdleStates->ReasonFlags = 0;
if( !IdleStates->InterfaceVersion )
{
v13 = PpmIdlePrepare(Prcb, DeepSleepEnabled, &EnterTime, &InterruptTime, &DurationHint, &Affinity);
v14 = v13;
LODWORD(SelectedProcessorState) = v13;
if( v13 != -2 )
{
if( v13 == -1 )
{
++IdleAccounting->AbortCount;
return;
}
PlatformIdleStateIndex = IdleStates->PrepareInfo.PlatformIdleStateIndex;
HIDWORD(SelectedProcessorState) = PlatformIdleStateIndex;
if( PlatformIdleStateIndex != -1 )
{
*IdleStates->CoordinatedSelection.Selection = PlatformIdleStateIndex;
IdleStates->CoordinatedSelection.SelectedStates = 1;
}
v5 = DurationHint;
goto LABEL_27;
}
LABEL_56:
HalProcessorIdle();
return;
}
if( PpmIdleVetoBias && IdleStates->StrictVetoBias )
goto LABEL_56;
PpmIdleSelectStates(
Prcb,
&EnterTime,
&InterruptTime,
DeepSleepEnabled,
&SelectedProcessorState,
(UINT64 *)((char *)&SelectedProcessorState + 4),
SynchronizedTransition);
v14 = SelectedProcessorState;
LABEL_27:
TargetState = IdleStates->TargetState;
if( v14 != (_DWORD)TargetState )
{
IdleStates->OldState = TargetState;
IdleStates->TargetState = v14;
PpmEventIdleStateChange(v14, TargetState);
}
if( IdleAccounting->TotalTransitions++ == -1 )
PpmResetProcessorIdleAccounting(IdleAccounting, EnterTime);
v18 = Prcb->PowerState.IdleStates;
v19 = 0;
InterruptsEnabled = IdleStates->State[v14].InterruptsEnabled;
Count = Affinity.Count;
if( Affinity.Count )
{
while( !Affinity.Bitmap[v19] )
{
if( ++v19 >= Affinity.Count )
goto LABEL_34;
}
v18->ReasonFlags |= 0x400u;
if( KiSerializeTimerExpiration && v5 )
PpmSetPlatformIdleDurationHint(v5);
Count = Affinity.Count;
}
LABEL_34:
if( !(_BYTE)KiDynamicTickDisableReason
&& !PpmIpiLastClockOwnerDisable
&& !Prcb->ClockOwner
&& (*(&KiProcessorBlock + (unsigned int)KiClockTimerOwner))->ClockOwner
&& !InterruptsEnabled )
{
CurrentPrcb = KeGetCurrentPrcb();
LODWORD(LookupIndex) = 0;
ParentNode = CurrentPrcb->ParentNode;
v24 = ParentNode->Affinity.Reserved[0];
if( (ParentNode->DeepIdleSet & ~(1i64 << CurrentPrcb->GroupIndex)) == (ParentNode->Affinity.Mask & ~(1i64 << (KiProcessorIndexToNumberMappingTable[CurrentPrcb->Number] & 0x3F))) )
{
while( 1 )
{
NextNode = MmGetNextNode(v24, &LookupIndex);
if( NextNode == -1 )
break;
if( *(_QWORD *)(KeNodeBlock[NextNode] + 64) != *(_QWORD *)(KeNodeBlock[NextNode] + 136) )
goto LABEL_40;
}
if( ((Affinity.Bitmap[(unsigned __int64)(unsigned int)KiProcessorIndexToNumberMappingTable[v26] >> 6] >> (KiProcessorIndexToNumberMappingTable[v26] & 0x3F)) & 1) == 0 )
{
KeAddProcessorAffinityEx(&Affinity.Count, (unsigned int)v26);
v18->ReasonFlags |= 0x800u;
}
}
LABEL_40:
v14 = SelectedProcessorState;
Count = Affinity.Count;
}
if( Count )
{
while( !Affinity.Bitmap[v1] )
{
if( ++v1 >= Count )
goto LABEL_44;
}
HalRequestIpi(IpiAffinity, &Affinity);
}
LABEL_44:
LOBYTE(GlobalHintFloor) = DeepSleepEnabled[0];
PpmIdleExecuteTransition(
Prcb,
v14,
HIDWORD(SelectedProcessorState),
SynchronizedTransition[0],
(UINT64)GlobalHintFloor,
EnterTime,
InterruptTime);
}Referenced by:
KiIdleLoop