PpmUpdatePerformanceFeedback
CHAR __fastcall PpmUpdatePerformanceFeedback(_KPRCB *Prcb, UINT8 a2, CHAR a3, CHAR a4, INT64 a5){
unsigned int v5;
bool v7;
char v11;
unsigned __int64 v12;
_PROC_FEEDBACK *p_PerfFeedback;
int v14;
_PROC_FEEDBACK_COUNTER **Counters;
char v16;
unsigned int i;
unsigned __int8 Affinitized;
__int16 v19;
bool v20;
UINT64 v21;
unsigned __int64 *ScaledTime;
__int64 v23;
__int64 v24;
void(__fastcall *v25)(__int64, unsigned int *);
__int64 v26;
__int64 v27;
unsigned __int64 v28;
__int64 v29;
unsigned __int64 v30;
unsigned int v31;
UINT64 v32;
unsigned int UserTime;
unsigned int KernelTime;
unsigned int v35;
unsigned int v36;
_QWORD *v37;
unsigned __int64 UnaccountedKernelTime;
UINT64 v40;
UINT64 v41;
__int64 v42;
UINT64 ActiveTscCount;
UINT64 IdleTime;
unsigned __int64 v45;
UINT64 PpmStatsForProcessor;
UINT64 v47;
UINT64 v48;
int v49;
unsigned __int64 v50;
unsigned int v51;
v5 = 0;
v7 = Prcb->PowerState.Hypervisor == ProcHypervisorHvCounters;
v51 = 0;
PpmStatsForProcessor = 0i64;
ActiveTscCount = 0i64;
v48 = 0i64;
if( v7 )
{
v11 = 1;
v12 = Prcb->StatisticsPage[DWORD2(xmmword_140CED0E0)] >> 1;
}
else
{
v11 = 0;
v12 = 0i64;
}
v45 = v12;
p_PerfFeedback = &Prcb->PowerState.PerfFeedback;
if( a2
|| Prcb->PowerState.PerfFeedback.UnaccountedTime
|| Prcb->PowerState.PerfFeedback.UnaccountedKernelTime
&& (Prcb->UserTime != Prcb->PowerState.PerfFeedback.UserTimeLast
|| Prcb->KernelTime != Prcb->PowerState.PerfFeedback.KernelTimeLast)
|| a3 && v12 != Prcb->PowerState.PerfFeedback.IdleGenerationNumberLast )
{
v14 = 2;
Counters = Prcb->PowerState.PerfFeedback.Counters;
v16 = 0;
for( i = 0; i < 2; ++i )
{
if( *Counters )
{
Affinitized = (*Counters)->Affinitized;
if( Affinitized && a3 )
return 0;
if( Affinitized )
v16 = 1;
if( v14 == 2 )
v14 = i;
}
++Counters;
}
if( v16 || a2 || !a4 )
{
v19 = v49;
_disable();
v20 = (v19 & 0x200) != 0;
if( _interlockedbittestandset64((volatile signed __int32 *)p_PerfFeedback, 0i64) )
KxWaitForSpinLockAndAcquire(&Prcb->PowerState.PerfFeedback.Lock);
v21 = _InterlockedExchange64(&Prcb->PowerState.PerfFeedback.UnaccountedTime, 0i64);
if( v11 )
{
IdleTime = 0i64;
PpmStatsForProcessor = HvlGetPpmStatsForProcessor(Prcb, &IdleTime, &ActiveTscCount);
v48 = IdleTime;
v21 = PpmStatsForProcessor - IdleTime - Prcb->PowerState.PerfFeedback.HvActiveTimeLast;
Prcb->PowerState.PerfFeedback.HvActiveTimeLast = PpmStatsForProcessor - IdleTime;
}
Prcb->PowerState.PerfFeedback.UnscaledTime += v21;
ScaledTime = Prcb->PowerState.PerfFeedback.ScaledTime;
do
{
v23 = *(ScaledTime - 5);
if( v23 )
{
v24 = *(_QWORD *)(v23 + 40);
v7 = *(_BYTE *)(v23 + 33) == 0;
v42 = 0i64;
v50 = 0i64;
v25 = *(void(__fastcall **)(__int64, unsigned int *))v23;
if( v7 )
{
v25(v24, &v51);
v31 = v51;
}
else
{
((void(__fastcall *)(__int64, _QWORD, unsigned __int64 *, __int64 *))v25)(v24, a2, &v50, &v42);
v26 = *(_QWORD *)(v23 + 16);
if( v50 != v26 )
{
v27 = *(_QWORD *)(v23 + 8);
v28 = v50 - v26;
v30 = (v42 - v27) * *(unsigned __int8 *)(v23 + 35);
v50 = v28;
v42 -= v27;
v29 = v42;
*(_DWORD *)(v23 + 24) = v30 / v28;
*(_QWORD *)(v23 + 16) = v28 + v26;
*(_QWORD *)(v23 + 8) = v27 + v29;
}
v31 = *(_DWORD *)(v23 + 24);
v51 = v31;
}
v32 = v21 * v31;
*ScaledTime += v32;
if( v5 == Prcb->PowerState.PerfFeedback.KernelTimesIndex )
Prcb->PowerState.PerfFeedback.UnaccountedKernelTime += v32;
}
++v5;
++ScaledTime;
}
while( v5 < 2 );
if( Prcb->PowerState.PerfFeedback.KernelTimesIndex == 2 )
Prcb->PowerState.PerfFeedback.UnaccountedKernelTime += 100 * v21;
UserTime = Prcb->UserTime;
KernelTime = Prcb->KernelTime;
v35 = KernelTime - Prcb->PowerState.PerfFeedback.KernelTimeLast;
v36 = v35 + UserTime - Prcb->PowerState.PerfFeedback.UserTimeLast;
if( v36 )
{
UnaccountedKernelTime = Prcb->PowerState.PerfFeedback.UnaccountedKernelTime;
Prcb->PowerState.PerfFeedback.UnaccountedKernelTime = 0i64;
Prcb->PowerState.PerfFeedback.UserTimeLast = UserTime;
Prcb->PowerState.PerfFeedback.KernelTimeLast = KernelTime;
if( v35 )
{
if( v36 != 1 )
v35 /= v36;
v51 = v35;
Prcb->PowerState.PerfFeedback.PerformanceScaledKernelTime += UnaccountedKernelTime * v35;
}
}
Prcb->PowerState.PerfFeedback.IdleGenerationNumberLast = v45;
_InterlockedAnd64((volatile signed __int64 *)p_PerfFeedback, 0i64);
if( v20 )
_enable();
}
}
v37 = (_QWORD *)a5;
if( a5 )
{
v40 = PpmStatsForProcessor;
if( PpmStatsForProcessor )
{
v41 = v48;
}
else
{
v47 = 0i64;
v40 = HvlGetPpmStatsForProcessor(Prcb, &v47, &ActiveTscCount);
v41 = v47;
}
*v37 = v40;
v37[2] = ActiveTscCount;
v37[1] = v41;
}
return 1;
}Referenced by:
PpmContinueActiveTimeAccumulation
PpmIdleExecuteTransition
PpmPerfApplyProcessorState
PpmSnapPerformanceAccumulation