PopGetIdleTimesCallback
NTSTATUS __stdcall PopGetIdleTimesCallback(_KPRCB *Prcb, UINT64 Param1, UINT64 Param2){
struct _KPRCB *CurrentPrcb;
_BOOL8 v7;
unsigned __int64 v8;
_DWORD *v9;
_QWORD *v10;
signed __int64 IdleTimeEntry;
signed __int64 v12;
UINT64 v13;
signed __int64 v14;
signed __int64 v15;
UINT64 v16;
unsigned int v17;
unsigned int v18;
unsigned __int64 v19;
_PPM_IDLE_STATES *v21;
unsigned int i;
unsigned int StateCount;
_DWORD *v24;
__int64 v25;
int v26;
int v27;
int v28;
_DWORD *v29;
UINT64 v30;
UINT64 TotalTime;
UINT64 v32;
unsigned int v33;
_QWORD *v34;
_PROC_IDLE_ACCOUNTING *IdleAccounting;
_PPM_IDLE_STATES *IdleStates;
_QWORD *v37;
UINT64 PerformanceCounter;
unsigned int SpareLong0;
unsigned int KernelTime;
CurrentPrcb = KeGetCurrentPrcb();
v7 = CurrentPrcb != Prcb;
v8 = 0i64;
v9 = 0i64;
v10 = 0i64;
if( CurrentPrcb != Prcb )
{
_m_prefetchw((const void *)&Prcb->PowerState.IdleTimeEntry);
IdleTimeEntry = Prcb->PowerState.IdleTimeEntry;
do
{
v12 = IdleTimeEntry;
IdleTimeEntry = _InterlockedCompareExchange64(
(volatile signed __int64 *)&Prcb->PowerState.IdleTimeEntry,
IdleTimeEntry,
IdleTimeEntry);
}
while( v12 != IdleTimeEntry );
v8 = IdleTimeEntry;
if( !IdleTimeEntry )
return -1073741823;
}
IdleAccounting = Prcb->PowerState.IdleAccounting;
IdleStates = Prcb->PowerState.IdleStates;
PerformanceCounter = KeQueryPerformanceCounter(0i64);
v13 = PerformanceCounter;
SpareLong0 = Prcb->IdleThread->Tcb.SchedulerApc.SpareLong0;
KernelTime = Prcb->KernelTime;
if( Param1 )
{
*(_OWORD *)Param1 = 0i64;
*(_OWORD *)(Param1 + 16) = 0i64;
*(_OWORD *)(Param1 + 32) = 0i64;
if( IdleAccounting )
{
v21 = IdleStates;
if( IdleStates )
{
for( i = 0; ; ++i )
{
StateCount = IdleAccounting->StateCount;
v24 = v9;
v33 = i;
if( IdleAccounting->StateCount >= v21->ProcessorIdleCount )
StateCount = v21->ProcessorIdleCount;
v37 = v10;
if( i >= StateCount )
{
v13 = PerformanceCounter;
*(_QWORD *)Param1 = PpmConvertTime(IdleAccounting->PriorIdleTime, PopQpcFrequency, 0x989680ui64);
break;
}
v25 = i;
if( v21->State[v25].StateType )
{
if( v21->State[v25].StateType == 1 )
{
v26 = 1;
goto LABEL_33;
}
if( v21->State[v25].StateType == 2 )
{
v26 = 2;
goto LABEL_33;
}
}
else if( v21->State[v25].ContextRetained )
{
v26 = 2 - (v21->State[v25].CacheCoherent != 0);
goto LABEL_33;
}
v26 = 3;
LABEL_33:
v27 = v26 - 1;
if( v27 )
{
v28 = v27 - 1;
if( v28 )
{
if( v28 == 1 )
{
v29 = (_DWORD *)(Param1 + 40);
v30 = Param1 + 24;
}
else
{
v29 = 0i64;
v30 = 0i64;
}
}
else
{
v29 = (_DWORD *)(Param1 + 36);
v30 = Param1 + 16;
}
}
else
{
v29 = (_DWORD *)(Param1 + 32);
v30 = Param1 + 8;
}
v9 = v29;
v10 = (_QWORD *)v30;
v34 = (_QWORD *)v30;
if( i != v21->ActualState )
{
v10 = v37;
if( i != v21->ActualState )
v9 = v24;
}
if( v29 && v30 )
{
*v29 += IdleAccounting->State[i].FailureCount + IdleAccounting->State[i].SuccessCount;
TotalTime = IdleAccounting->State[i].TotalTime;
if( v21->ActualState == i )
TotalTime += Prcb->PowerState.IdleTimeLast;
v32 = PpmConvertTime(TotalTime, PopQpcFrequency, 0x989680ui64);
i = v33;
v21 = IdleStates;
*v34 += v32;
}
}
}
}
}
if( Param2 )
{
if( !v7 )
PpmContinueActiveTimeAccumulation(Prcb, v13);
*(_QWORD *)(Param2 + 8) = PpmConvertTime(Prcb->PowerState.PerfFeedback.StallTime, PopQpcFrequency, 0x989680ui64);
}
if( !v7 )
goto LABEL_18;
_m_prefetchw((const void *)&Prcb->PowerState.IdleTimeEntry);
v14 = Prcb->PowerState.IdleTimeEntry;
do
{
v15 = v14;
v14 = _InterlockedCompareExchange64((volatile signed __int64 *)&Prcb->PowerState.IdleTimeEntry, v14, v14);
}
while( v15 != v14 );
if( v8 != v14 )
return -1073741823;
if( v13 > v8 )
{
v16 = PpmConvertTime(v13 - v8, PopQpcFrequency, 0x989680ui64);
if( v10 && v9 )
{
++*v9;
*v10 += v16;
}
v17 = SpareLong0;
v18 = KernelTime;
if( v16 > (unsigned int)KeMaximumIncrement )
{
v19 = v16 / (unsigned int)KeMaximumIncrement;
v17 = v19 + SpareLong0 - 1;
v18 = v19 + KernelTime - 1;
}
}
else
{
LABEL_18:
v18 = KernelTime;
v17 = SpareLong0;
}
if( Param1 )
{
if( IdleAccounting && IdleStates )
*(_QWORD *)Param1 += *(_QWORD *)(Param1 + 8) + *(_QWORD *)(Param1 + 16) + *(_QWORD *)(Param1 + 24);
else
*(_QWORD *)Param1 = v17 * (unsigned __int64)(unsigned int)KeMaximumIncrement;
}
if( Param2 )
{
*(_DWORD *)Param2 = v17;
*(_DWORD *)(Param2 + 4) = v18;
}
return 0;
}Referenced by:
PoGetIdleTimes