PpmEstimateIdleDuration
VOID __stdcall PpmEstimateIdleDuration(
_KPRCB *Prcb,
UINT8 DeepSleepEnabled,
UINT64 CurrentInterruptTime,
UINT64 MinimumDuration,
UINT64 *ExpectedIdleDuration,
UINT64 *MaximumIdleDuration,
_KEXPECTED_WAKE_REASON *ExpectedWakeReason,
UINT64 *Flags){
char v8;
UINT64 v12;
_PPM_IDLE_STATES *IdleStates;
unsigned __int64 v14;
UINT8 PlatformIdle;
int v16;
unsigned int InterruptRate;
unsigned int v18;
unsigned int i;
unsigned __int64 v20;
unsigned int v21;
UINT64 v22;
int v23;
_KPRCB *v24;
unsigned __int64 IdleTimeExpiration;
UINT64 ProcIndex;
_KEXPECTED_WAKE_REASON v27[2];
_KEXPECTED_WAKE_REASON *v28;
UINT64 *v29;
_KAFFINITY_ENUMERATION_CONTEXT Context;
_KAFFINITY_EX IdleConstrainedMask;
int *v32;
v8 = CurrentInterruptTime;
v29 = MaximumIdleDuration;
v28 = ExpectedWakeReason;
*(_DWORD *)(&Context.CurrentIndex + 1) = 0;
*(&Context.CurrentIndex + 3) = 0;
memset(&IdleConstrainedMask, 0i64, sizeof(IdleConstrainedMask));
IdleStates = Prcb->PowerState.IdleStates;
v14 = -1i64;
*(_QWORD *)v27 = 0i64;
LODWORD(ProcIndex) = 0;
PlatformIdle = IdleStates->PrepareInfo.Constraints.PlatformIdle;
v16 = 0;
*v32 = 0;
if( Prcb->ClockOwner )
{
v16 = 8;
*v32 = 8;
}
if( DeepSleepEnabled )
*v32 = v16 | 4;
LOBYTE(v12) = v8;
KeEstimateClockTickDuration(Prcb, PlatformIdle, DeepSleepEnabled, v12, (UINT64 *)MinimumDuration, v27);
InterruptRate = Prcb->InterruptRate;
v18 = 0;
for( i = InterruptRate; i; i >>= 4 )
v18 += KeMaximumIncrement;
v20 = v18;
if( !DeepSleepEnabled && InterruptRate )
{
v21 = (unsigned int)KeMaximumIncrement / (InterruptRate + 1);
if( !v21 )
v21 = 1;
v14 = v21;
}
if( *(_QWORD *)v27 <= v14 )
{
v14 = *(_QWORD *)v27;
v20 = *(_QWORD *)v27;
}
else
{
if( *(_QWORD *)v27 < (unsigned __int64)v18 )
v20 = *(_QWORD *)v27;
*v32 |= 1u;
}
if( PpmIdleDurationExpirationTimeout && Prcb->ClockOwner && PpmGetIdleConstrainedMask(&IdleConstrainedMask) )
{
v22 = 0i64;
Context.CurrentMask = IdleConstrainedMask.Bitmap[0];
Context.Affinity = &IdleConstrainedMask;
Context.CurrentIndex = 0;
while( 1 )
{
KeEnumerateNextProcessor(&ProcIndex, &Context);
if( v23 )
break;
v24 = KeGetPrcb((unsigned int)ProcIndex);
IdleTimeExpiration = v24->PowerState.IdleTimeExpiration;
if( IdleTimeExpiration != -1i64 && IdleTimeExpiration > v22 )
v22 = v24->PowerState.IdleTimeExpiration;
}
if( v22 && v20 + MinimumDuration > v22 )
{
*v32 |= 0x2000u;
v20 = v22 > MinimumDuration ? (unsigned int)(v22 - MinimumDuration) : 1i64;
if( v20 < v14 )
v14 = v20;
}
}
if( v14 < (unsigned __int64)ExpectedIdleDuration )
{
*v32 |= 0x1000u;
v14 = (unsigned __int64)ExpectedIdleDuration;
v20 = (unsigned __int64)ExpectedIdleDuration;
}
*(_QWORD *)v28 = v20;
*v29 = v14;
}Referenced by:
PpmIdleSelectStates