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