PpmSnapPerformanceAccumulation

UINT8 __stdcall PpmSnapPerformanceAccumulation(
        _KPRCB *Prcb,
        UINT8 Reset,
        UINT8 Remote,
        UINT8 SnapPmc,
        _PROC_PERF_CHECK_SNAP *Snap){
  unsigned __int64 *a5; 
  UINT8 v6; 
  UINT64 v9; 
  INT64 v10; 
  __int64 v11; 
  __int64 v12; 
  volatile unsigned __int64 v13; 
  UINT64 v14; 
  signed __int64 IdleTimeEntry; 
  signed __int64 v16; 
  UINT8 result; 
  INT64 v18; 
  __int64 v19; 
  __int64 v20; 
  volatile unsigned __int64 QpcBias; 
  unsigned __int64 v22; 
  unsigned __int64 v23; 
  unsigned __int64 v24; 
  unsigned __int64 CyclesLast; 
  __int64 v26; 
  unsigned __int64 IdleTimeTotal; 
  unsigned __int64 CyclesActive; 
  unsigned __int64 v29; 
  __int64 v30; 
  unsigned __int64 v31; 
  signed __int64 v32; 
  signed __int64 v33; 
  __int64 v34; 
  __int64 v35; 
  __int64 v36; 
  __int64 v37; 
  __int64 v38; 
  unsigned __int64 v39; 
  __int64 v40; 
  int v41; 
  unsigned __int64 v42; 
  __int64 v43; 
  __int64 v44; 
  unsigned __int64 v45; 
  signed __int64 v46; 
  __int64 v47; 
  bool v48; 
  __int64 v49; 
  __int64 v50; 
  __int64 v51; 
  __int64 v52; 
  unsigned __int64 v53; 
  __int64 v54; 
  int v55; 
  unsigned __int64 v56; 
  __int64 v57; 
  __int64 v58; 
  unsigned __int64 v59; 
  signed __int64 v60; 
  __int64 v61; 
  UINT64 v62; 
  unsigned __int64 v63; 
  __int64 v64; 
  __int64 v65; 
  __int64 v66; 
  __int64 v67; 
  __int64 v68; 
  unsigned __int64 v69; 
  __int64 v70; 
  int v71; 
  unsigned __int64 v72; 
  __int64 v73; 
  __int64 v74; 
  unsigned __int64 v75; 
  signed __int64 v76; 
  __int64 v77; 
  __int64 v78; 
  __int64 v79; 
  __int64 v80; 
  __int64 v81; 
  unsigned __int64 v82; 
  __int64 v83; 
  int v84; 
  unsigned __int64 v85; 
  __int64 v86; 
  __int64 v87; 
  unsigned __int64 v88; 
  signed __int64 v89; 
  __int64 v90; 
  UINT64 v91; 
  signed __int32 v92[8]; 
  UINT8 v93; 
  UINT8 v94; 
  UINT64 FromFrequency; 
  UINT64 v96; 
  __int64 v97; 
  __int128 v98; 
  __int64 v99; 

  a5 = 0i64;
  v93 = SnapPmc;
  v94 = Reset;
  v99 = 0i64;
  v6 = SnapPmc;
  v97 = 0i64;
  v9 = 0i64;
  v98 = 0i64;
  if( !Remote )
  {
    _disable();
    v18 = HalpPerformanceCounter;
    if( *(_DWORD *)(HalpPerformanceCounter + 228) == 5 )
    {
      v96 = 10000000i64;
      if( !HalpTimerReferencePage )
      {
        if( *(_DWORD *)(HalpPerformanceCounter + 220) == 64 )
        {
          HalpTimerGetInternalData((_KDPC *)HalpPerformanceCounter, (PVOID)Reset, (PVOID)Remote, (PVOID)SnapPmc);
          v65 = (*(__int64(__fastcall **)(__int64))(v18 + 112))(v64);
          v66 = *(_QWORD *)(v18 + 208);
          *(_QWORD *)&Reset = v65;
        }
        else
        {
          do
          {
            v66 = *(_QWORD *)(v18 + 208);
            do
            {
              v67 = *(_QWORD *)(v18 + 200);
              HalpTimerGetInternalData((_KDPC *)v18, (PVOID)Reset, (PVOID)Remote, (PVOID)SnapPmc);
              v69 = (*(__int64(__fastcall **)(__int64))(v18 + 112))(v68);
              _InterlockedOr(v92, 0);
              v70 = *(_QWORD *)(v18 + 200);
            }
            while( v67 != v70 );
          }
          while( v66 != *(_QWORD *)(v18 + 208) );
          v71 = *(_DWORD *)(v18 + 220);
          v72 = v67 ^ v69;
          if( _bittest64((const __int64 *)&v72, (unsigned __int8)(v71 - 1)) )
          {
            v73 = 1i64;
            if( v71 == 64 )
              v74 = -1i64;
            else
              v74 = (1i64 << v71) - 1;
            if( v71 != 64 )
              v73 = 1i64 << v71;
            v75 = v67 & v74;
            *(_QWORD *)&Reset = v69 | v67 ^ v75;
            if( v69 < v75 )
              *(_QWORD *)&Reset = v73 + Reset;
            _InterlockedCompareExchange64((volatile signed __int64 *)(v18 + 200), Reset, v76);
          }
          else
          {
            if( v71 == 64 )
              v77 = -1i64;
            else
              v77 = (1i64 << v71) - 1;
            *(_QWORD *)&Reset = v69 | v67 & ~v77;
          }
        }
        v14 = HalpTimerScaleCounter(v66 + Reset, *(_QWORD *)(v18 + 192), 0x989680ui64);
        goto LABEL_21;
      }
      if( (*(_DWORD *)(HalpPerformanceCounter + 224) & 0x10000) != 0 )
        v19 = *(_QWORD *)(HalpPerformanceCounter + 72)
            + *(_DWORD *)(HalpPerformanceCounter + 80) * KeGetPcr()->Prcb.Number;
      else
        v19 = *(_QWORD *)(HalpPerformanceCounter + 72);
      v20 = (*(__int64(__fastcall **)(__int64))(HalpPerformanceCounter + 112))(v19);
      QpcBias = KUSER_SHARED_DATA.QpcBias;
      *(_OWORD *)(&Reset - 8) = (unsigned __int64)v20
                              * (unsigned __int128)*((unsigned __int64 *)HalpTimerReferencePage + 1);
    }
    else
    {
      v48 = *(_DWORD *)(HalpPerformanceCounter + 220) == 64;
      v96 = *(_QWORD *)(HalpPerformanceCounter + 192);
      if( v48 )
      {
        HalpTimerGetInternalData((_KDPC *)HalpPerformanceCounter, (PVOID)Reset, (PVOID)Remote, (PVOID)SnapPmc);
        v79 = (*(__int64(__fastcall **)(__int64))(v18 + 112))(v78);
        QpcBias = *(_QWORD *)(v18 + 208);
        *(_QWORD *)&Reset = v79;
      }
      else
      {
        do
        {
          QpcBias = *(_QWORD *)(v18 + 208);
          do
          {
            v80 = *(_QWORD *)(v18 + 200);
            HalpTimerGetInternalData((_KDPC *)v18, (PVOID)Reset, (PVOID)Remote, (PVOID)SnapPmc);
            v82 = (*(__int64(__fastcall **)(__int64))(v18 + 112))(v81);
            _InterlockedOr(v92, 0);
            v83 = *(_QWORD *)(v18 + 200);
          }
          while( v80 != v83 );
        }
        while( QpcBias != *(_QWORD *)(v18 + 208) );
        v84 = *(_DWORD *)(v18 + 220);
        v85 = v80 ^ v82;
        if( _bittest64((const __int64 *)&v85, (unsigned __int8)(v84 - 1)) )
        {
          v86 = 1i64;
          if( v84 == 64 )
            v87 = -1i64;
          else
            v87 = (1i64 << v84) - 1;
          if( v84 != 64 )
            v86 = 1i64 << v84;
          v88 = v80 & v87;
          *(_QWORD *)&Reset = v82 | v80 ^ v88;
          if( v82 < v88 )
            *(_QWORD *)&Reset = v86 + Reset;
          _InterlockedCompareExchange64((volatile signed __int64 *)(v18 + 200), Reset, v89);
        }
        else
        {
          if( v84 == 64 )
            v90 = -1i64;
          else
            v90 = (1i64 << v84) - 1;
          *(_QWORD *)&Reset = v82 | v80 & ~v90;
        }
      }
    }
    v14 = Reset + QpcBias;
LABEL_21:
    if( v18 != HalpOriginalPerformanceCounter && HalpOriginalPerformanceCounter )
    {
      v91 = *(_QWORD *)(HalpOriginalPerformanceCounter + 192);
      if( *(_DWORD *)(HalpOriginalPerformanceCounter + 228) == 5 )
        v91 = 10000000i64;
      v14 = HalpTimerScaleCounter(v14, v96, v91);
    }
    v22 = __rdtsc();
    if( (Prcb->FeatureBits & 0x8000000000i64) != 0 )
      v23 = __readmsr(0xDB2u);
    else
      v23 = 0i64;
    v24 = v14 - Prcb->PowerState.PerfFeedback.LastUpdateTime;
    _InterlockedExchangeAdd64(&Prcb->PowerState.PerfFeedback.UnaccountedTime, v24);
    if( (Prcb->FeatureBits & 0x8000000000i64) != 0 )
      Prcb->PowerState.PerfFeedback.StallTime += PpmConvertTime(
                                                   v24,
                                                   v22 - Prcb->PowerState.PerfFeedback.CyclesLast,
                                                   v23 - Prcb->PowerState.PerfFeedback.StallCyclesLast);
    CyclesLast = Prcb->PowerState.PerfFeedback.CyclesLast;
    Prcb->PowerState.PerfFeedback.LastUpdateTime = v14;
    if( v22 > CyclesLast )
      Prcb->PowerState.PerfFeedback.CyclesActive += v22 - CyclesLast;
    Prcb->PowerState.PerfFeedback.CyclesLast = v22;
    a5 = 0i64;
    if( (Prcb->FeatureBits & 0x8000000000i64) != 0 )
      Prcb->PowerState.PerfFeedback.StallCyclesLast = v23;
    v6 = v93;
    goto LABEL_31;
  }
  v10 = HalpPerformanceCounter;
  if( *(_DWORD *)(HalpPerformanceCounter + 228) != 5 )
  {
    v48 = *(_DWORD *)(HalpPerformanceCounter + 220) == 64;
    FromFrequency = *(_QWORD *)(HalpPerformanceCounter + 192);
    if( v48 )
    {
      HalpTimerGetInternalData((_KDPC *)HalpPerformanceCounter, (PVOID)Reset, (PVOID)Remote, (PVOID)SnapPmc);
      v50 = (*(__int64(__fastcall **)(__int64))(v10 + 112))(v49);
      v13 = *(_QWORD *)(v10 + 208);
      *(_QWORD *)&Reset = v50;
    }
    else
    {
      do
      {
        v13 = *(_QWORD *)(v10 + 208);
        do
        {
          v51 = *(_QWORD *)(v10 + 200);
          HalpTimerGetInternalData((_KDPC *)v10, (PVOID)Reset, (PVOID)Remote, (PVOID)SnapPmc);
          v53 = (*(__int64(__fastcall **)(__int64))(v10 + 112))(v52);
          _InterlockedOr(v92, 0);
          v54 = *(_QWORD *)(v10 + 200);
        }
        while( v51 != v54 );
      }
      while( v13 != *(_QWORD *)(v10 + 208) );
      v55 = *(_DWORD *)(v10 + 220);
      v56 = v51 ^ v53;
      if( _bittest64((const __int64 *)&v56, (unsigned __int8)(v55 - 1)) )
      {
        v57 = 1i64;
        if( v55 == 64 )
          v58 = -1i64;
        else
          v58 = (1i64 << v55) - 1;
        if( v55 != 64 )
          v57 = 1i64 << v55;
        v59 = v51 & v58;
        *(_QWORD *)&Reset = v53 | v51 ^ v59;
        if( v53 < v59 )
          *(_QWORD *)&Reset = v57 + Reset;
        _InterlockedCompareExchange64((volatile signed __int64 *)(v10 + 200), Reset, v60);
        a5 = 0i64;
      }
      else
      {
        if( v55 == 64 )
          v61 = -1i64;
        else
          v61 = (1i64 << v55) - 1;
        *(_QWORD *)&Reset = v53 | v51 & ~v61;
        a5 = 0i64;
      }
    }
    goto LABEL_7;
  }
  FromFrequency = 10000000i64;
  if( HalpTimerReferencePage )
  {
    if( (*(_DWORD *)(HalpPerformanceCounter + 224) & 0x10000) != 0 )
      v11 = *(_QWORD *)(HalpPerformanceCounter + 72)
          + *(_DWORD *)(HalpPerformanceCounter + 80) * KeGetPcr()->Prcb.Number;
    else
      v11 = *(_QWORD *)(HalpPerformanceCounter + 72);
    v12 = (*(__int64(__fastcall **)(__int64))(HalpPerformanceCounter + 112))(v11);
    v13 = KUSER_SHARED_DATA.QpcBias;
    *(_OWORD *)(&Reset - 8) = (unsigned __int64)v12
                            * (unsigned __int128)*((unsigned __int64 *)HalpTimerReferencePage + 1);
LABEL_7:
    v14 = Reset + v13;
    goto LABEL_8;
  }
  if( *(_DWORD *)(HalpPerformanceCounter + 220) == 64 )
  {
    HalpTimerGetInternalData((_KDPC *)HalpPerformanceCounter, (PVOID)Reset, (PVOID)Remote, (PVOID)SnapPmc);
    v35 = (*(__int64(__fastcall **)(__int64))(v10 + 112))(v34);
    v36 = *(_QWORD *)(v10 + 208);
    *(_QWORD *)&Reset = v35;
  }
  else
  {
    do
    {
      v36 = *(_QWORD *)(v10 + 208);
      do
      {
        v37 = *(_QWORD *)(v10 + 200);
        HalpTimerGetInternalData((_KDPC *)v10, (PVOID)Reset, (PVOID)Remote, (PVOID)SnapPmc);
        v39 = (*(__int64(__fastcall **)(__int64))(v10 + 112))(v38);
        _InterlockedOr(v92, 0);
        v40 = *(_QWORD *)(v10 + 200);
      }
      while( v37 != v40 );
    }
    while( v36 != *(_QWORD *)(v10 + 208) );
    v41 = *(_DWORD *)(v10 + 220);
    v42 = v37 ^ v39;
    if( _bittest64((const __int64 *)&v42, (unsigned __int8)(v41 - 1)) )
    {
      v43 = 1i64;
      if( v41 == 64 )
        v44 = -1i64;
      else
        v44 = (1i64 << v41) - 1;
      if( v41 != 64 )
        v43 = 1i64 << v41;
      v45 = v37 & v44;
      *(_QWORD *)&Reset = v39 | v37 ^ v45;
      if( v39 < v45 )
        *(_QWORD *)&Reset = v43 + Reset;
      _InterlockedCompareExchange64((volatile signed __int64 *)(v10 + 200), Reset, v46);
      a5 = 0i64;
    }
    else
    {
      if( v41 == 64 )
        v47 = -1i64;
      else
        v47 = (1i64 << v41) - 1;
      *(_QWORD *)&Reset = v39 | v37 & ~v47;
      a5 = 0i64;
    }
  }
  v14 = HalpTimerScaleCounter(v36 + Reset, *(_QWORD *)(v10 + 192), 0x989680ui64);
LABEL_8:
  if( v10 != HalpOriginalPerformanceCounter && HalpOriginalPerformanceCounter )
  {
    v62 = *(_QWORD *)(HalpOriginalPerformanceCounter + 192);
    if( *(_DWORD *)(HalpOriginalPerformanceCounter + 228) == 5 )
      v62 = 10000000i64;
    v14 = HalpTimerScaleCounter(v14, FromFrequency, v62);
  }
  _m_prefetchw((const void *)&Prcb->PowerState.IdleTimeEntry);
  IdleTimeEntry = Prcb->PowerState.IdleTimeEntry;
  do
  {
    v16 = IdleTimeEntry;
    IdleTimeEntry = _InterlockedCompareExchange64(
                      (volatile signed __int64 *)&Prcb->PowerState.IdleTimeEntry,
                      IdleTimeEntry,
                      IdleTimeEntry);
  }
  while( v16 != IdleTimeEntry );
  v9 = IdleTimeEntry;
  if( IdleTimeEntry )
  {
    if( Prcb->PowerState.Hypervisor == ProcHypervisorHvCounters )
    {
      v63 = Prcb->StatisticsPage[DWORD2(xmmword_140CED0E0)];
      v9 = v63 >> 1;
      if( (v63 & 1) == 0 )
        v9 = 0i64;
    }
  }
  if( !v9 )
    return 0;
LABEL_31:
  memset(Snap, 0i64, sizeof(_PROC_PERF_CHECK_SNAP));
  Snap->CyclesAffinitized = Prcb->AffinitizedCycles + Prcb->CycleTime;
  Snap->TaggedThreadCycles[0] = Prcb->TaggedCycles[0];
  Snap->TaggedThreadCycles[1] = Prcb->TaggedCycles[1];
  Snap->TaggedThreadCycles[2] = Prcb->TaggedCycles[2];
  if( !Remote )
    _enable();
  if( Prcb->PowerState.Hypervisor == ProcHypervisorHvCounters )
    a5 = (unsigned __int64 *)&v98;
  result = PpmUpdatePerformanceFeedback(Prcb, v94, Remote, 0, (INT64)a5);
  if( result )
  {
    if( v6 && *(&stru_140C23628 + 764) )
    {
      LOBYTE(v26) = 1;
      (*(&stru_140C23628 + 764))(Prcb->Number, Remote, v26);
    }
    if( a5 )
    {
      v29 = *a5;
      IdleTimeTotal = a5[1];
      CyclesActive = a5[2];
      v30 = v97;
    }
    else
    {
      IdleTimeTotal = Prcb->PowerState.IdleTimeTotal;
      CyclesActive = Prcb->PowerState.PerfFeedback.CyclesActive;
      v29 = v9;
      if( v14 > v9 )
        v29 = v14;
      v30 = v9;
    }
    if( Prcb->PowerState.PerfFeedback.Counters[0] )
    {
      v31 = Prcb->PowerState.PerfFeedback.ScaledTime[0];
    }
    else if( Prcb->PowerState.PerfFeedback.Counters[1] )
    {
      v31 = Prcb->PowerState.PerfFeedback.ScaledTime[1];
    }
    else
    {
      v31 = 100 * Prcb->PowerState.PerfFeedback.UnscaledTime;
    }
    Snap->FrequencyScaledActive = v31;
    if( Prcb->PowerState.PerfFeedback.Counters[1] )
      v31 = Prcb->PowerState.PerfFeedback.ScaledTime[1];
    Snap->PerformanceScaledActive = v31;
    Snap->PerformanceScaledKernelActive = Prcb->PowerState.PerfFeedback.PerformanceScaledKernelTime;
    Snap->Stall = Prcb->PowerState.PerfFeedback.StallTime;
    Snap->ResponsivenessEvents = Prcb->DpcData[0].DpcCount;
    if( Remote )
    {
      _m_prefetchw((const void *)&Prcb->PowerState.IdleTimeEntry);
      v32 = Prcb->PowerState.IdleTimeEntry;
      do
      {
        v33 = v32;
        v32 = _InterlockedCompareExchange64((volatile signed __int64 *)&Prcb->PowerState.IdleTimeEntry, v32, v32);
      }
      while( v33 != v32 );
      if( v32 )
      {
        if( Prcb->PowerState.Hypervisor == ProcHypervisorHvCounters )
        {
          v32 = Prcb->StatisticsPage[DWORD2(xmmword_140CED0E0)] >> 1;
          if( (Prcb->StatisticsPage[DWORD2(xmmword_140CED0E0)] & 1) == 0 )
            v32 = 0i64;
        }
      }
      if( v9 != v32 )
        return 0;
      if( !a5 )
        IdleTimeTotal += v29 - v30;
    }
    else if( !a5 )
    {
      IdleTimeTotal += Prcb->PowerState.IdleTimeLast;
    }
    Snap->Time = v29;
    result = 1;
    Snap->CyclesActive = CyclesActive;
    Snap->Active = v29 - IdleTimeTotal;
  }
  return result;
}

Referenced by:

PpmCapturePerformanceDistributionCallback
PpmCheckSnapAllDeliveredPerformance
PpmGetThroughputInfoCallback
PpmPerfSnapDeliveredPerformance
PpmResetPerfTimes