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