KeQueryTotalCycleTimeThread

UINT64 __stdcall KeQueryTotalCycleTimeThread(_ETHREAD *Thread, UINT64 *CycleTimeStamp){
  struct _KPRCB *CurrentPrcb; 
  UINT64 v5; 
  UINT64 v6; 
  UINT64 v7; 
  unsigned __int64 v8; 
  bool v9; 
  unsigned __int8 CurrentIrql; 
  struct _KPRCB *v12; 
  __int64 v13; 
  int v14; 
  __int64 v15; 
  char v16; 
  int v17; 
  struct _KPRCB *v18; 
  UINT64 v19; 
  UINT64 SpinCount; 
  _KSHARED_READY_QUEUE *ControlReadyQueue; 
  _KPRCB *ControlPrcb; 
  int result; 
  INT64 result_4; 
  memset((INT64)&result, 0i64);
  ControlPrcb = 0i64;
  ControlReadyQueue = 0i64;
  if( Thread == (_ETHREAD *)KeGetCurrentThread() )
  {
    _disable();
    CurrentPrcb = KeGetCurrentPrcb();
    *((_BYTE *)CurrentPrcb + 32) = 1;
    v5 = __rdtsc();
    v6 = v5 - *((_QWORD *)CurrentPrcb + 4056);
    v7 = v6 + *((_QWORD *)Thread + 9);
    v8 = v6 + *((unsigned int *)Thread + 20);
    *((_QWORD *)Thread + 9) = v7;
    if( v8 > 0xFFFFFFFF )
      LODWORD(v8) = -1;
    *((_QWORD *)CurrentPrcb + 4056) = v5;
    v9 = (*((_BYTE *)Thread + 2) & 0x3E) == 0;
    *((_DWORD *)Thread + 20) = v8;
    if( !v9 )
      KiEndThreadAccountingPeriod(CurrentPrcb, (_KTHREAD *)Thread, v6);
    if( CycleTimeStamp )
      *CycleTimeStamp = v5;
    KiStartThreadCycleAccumulation(CurrentPrcb, (_KTHREAD *)Thread, 0);
    _enable();
    return v7;
  }
  else
  {
    CurrentIrql = KeGetCurrentIrql();
    __writecr8(2ui64);
    v12 = KeGetCurrentPrcb();
    LODWORD(SpinCount) = 0;
    while( _interlockedbittestandset64((volatile signed __int32 *)Thread + 16, 0i64) )
    {
      do
        KeYieldProcessorEx(&SpinCount);
      while( *((_QWORD *)Thread + 8) );
      v13 = *((_QWORD *)v12 + 4247);
      if( v13 && *((_BYTE *)v12 + 32) <= 1u )
      {
        v14 = *(_DWORD *)(v13 + 24) + 1;
        *(_DWORD *)(v13 + 24) = v14;
      }
    }
    KiAcquireThreadStateLock(Thread, &ControlPrcb, &ControlReadyQueue);
    if( v16 == 2 )
    {
      v17 = *((_DWORD *)Thread + 134);
      KiReleaseThreadStateLock(v15, (__int64)ControlPrcb, (volatile signed __int64 *)ControlReadyQueue);
      KiReleaseThreadLockSafe((INT64)Thread);
      result = 1310721;
      memset((INT64)&result_4, 0i64);
      KeAddProcessorAffinityEx(&result, v17);
      KeGetCurrentIrql();
      __writecr8(0xCui64);
      KiIpiSendPacket(0i64, (UINT16 *)&result, (INT64)xHalTimerWatchdogStop, 0i64, 0i64, 0i64);
      v18 = KeGetCurrentPrcb();
      while( *((_DWORD *)v18 + 2912) )
        _mm_pause();
      *CycleTimeStamp = __rdtsc();
      v19 = *((_QWORD *)Thread + 9);
    }
    else
    {
      if( *((_BYTE *)Thread + 113) )
        KeFlushProcessWriteBuffers(1u);
      *CycleTimeStamp = __rdtsc();
      v19 = *((_QWORD *)Thread + 9);
      KiReleaseThreadStateLock(v15, (__int64)ControlPrcb, (volatile signed __int64 *)ControlReadyQueue);
      KiReleaseThreadLockSafe((INT64)Thread);
    }
    __writecr8(CurrentIrql);
    return v19;
  }
}

Referenced by:

NtQueryInformationThread