KiUpdateTime

INT8 __stdcall KiUpdateTime(INT8 ProcessorMode, INT8 PreviousIrql){
  void *v2; 
  void *v3; 
  unsigned __int64 v4; 
  struct _KPRCB *CurrentPrcb; 
  __int16 v6; 
  char v7; 
  UINT8 v8; 
  volatile unsigned __int64 TickCountQuad; 
  bool v10; 
  signed __int64 TimeUpdateLock; 
  signed __int64 v12; 
  ULONG_PTR v13; 
  __int64 v14; 
  UINT64 v15; 
  unsigned __int128 v16; 
  UINT64 v17; 
  __int64 v18; 
  UINT64 v19; 
  UINT64 v20; 
  volatile unsigned __int64 v21; 
  EVENT_DESCRIPTOR *v22; 
  struct _KPRCB *v23; 
  UINT64 v24; 
  unsigned __int16 Count; 
  _KAFFINITY_EX *p_result; 
  __int64 v27; 
  unsigned __int16 v28; 
  unsigned __int64 v29; 
  __int64 v30; 
  bool v32; 
  __int64 v33; 
  __int64 v34; 
  __int64 v35; 
  signed __int64 v36; 
  UINT64 v37; 
  __int64 v38; 
  __int64 v39; 
  signed __int64 v40; 
  int v41; 
  __int64 v42; 
  volatile CCHAR v43; 
  unsigned __int64 v44; 
  __int64 v45; 
  __int64 v46; 
  __int64 v47; 
  signed __int64 v48; 
  __int64 v49; 
  __int64 v50; 
  unsigned __int64 v51; 
  signed __int64 v52; 
  int v53; 
  __int64 v54; 
  __int64 v55; 
  unsigned __int64 v56; 
  __int64 v57; 
  __int64 v58; 
  __int64 v59; 
  unsigned __int64 v60; 
  __int64 v61; 
  int v62; 
  __int64 v63; 
  signed __int32 v64[8]; 
  INT8 v65; 
  INT8 v66; 
  char SpinCount[12]; 
  __int64 v68; 
  __int64 v69; 
  _KAFFINITY_EX result; 
  int v71; 
  v65 = PreviousIrql;
  v66 = ProcessorMode;
  memset((INT64)&result, 0i64);
  CurrentPrcb = KeGetCurrentPrcb();
  v6 = v71;
  v7 = 0;
  v8 = 0;
  TickCountQuad = KUSER_SHARED_DATA.TickCountQuad;
  _disable();
  v10 = (v6 & 0x200) != 0;
  _m_prefetchw(&KUSER_SHARED_DATA.TimeUpdateLock);
  TimeUpdateLock = KUSER_SHARED_DATA.TimeUpdateLock;
  while( (TimeUpdateLock & 1) != 0 )
  {
    TimeUpdateLock = KUSER_SHARED_DATA.TimeUpdateLock;
LABEL_68:
    _mm_pause();
  }
  v12 = TimeUpdateLock;
  TimeUpdateLock = _InterlockedCompareExchange64(
                     (volatile signed __int64 *)&KUSER_SHARED_DATA.TimeUpdateLock,
                     TimeUpdateLock + 1,
                     TimeUpdateLock);
  if( v12 != TimeUpdateLock )
    goto LABEL_68;
  v13 = HalpPerformanceCounter;
  if( *(_DWORD *)(HalpPerformanceCounter + 228) != 5 )
  {
    v32 = *(_DWORD *)(HalpPerformanceCounter + 220) == 64;
    *(_QWORD *)&SpinCount[4] = *(_QWORD *)(HalpPerformanceCounter + 192);
    if( v32 )
    {
      HalpTimerGetInternalData((KDPC *)HalpPerformanceCounter, v2, v3, (PVOID)v4);
      v34 = (*(__int64(__fastcall **)(__int64))(v13 + 112))(v33);
      v35 = *(_QWORD *)(v13 + 208);
      v36 = v34;
    }
    else
    {
      do
      {
        v35 = *(_QWORD *)(v13 + 208);
        do
        {
          v38 = *(_QWORD *)(v13 + 200);
          HalpTimerGetInternalData((KDPC *)v13, v2, v3, (PVOID)v4);
          v4 = (*(__int64(__fastcall **)(__int64))(v13 + 112))(v39);
          _InterlockedOr(v64, 0);
          v40 = *(_QWORD *)(v13 + 200);
        }
        while( v38 != v40 );
      }
      while( v35 != *(_QWORD *)(v13 + 208) );
      v41 = *(_DWORD *)(v13 + 220);
      if( ((v38 ^ v4) & (1i64 << ((unsigned __int8)v41 - 1))) == 0 )
      {
        if( v41 == 64 )
          v42 = -1i64;
        else
          v42 = (1i64 << v41) - 1;
        v15 = v35 + (v4 | v38 & ~v42);
        goto LABEL_9;
      }
      v58 = 1i64 << v41;
      v59 = -1i64;
      if( v41 != 64 )
        v59 = v58 - 1;
      v60 = v38 & v59;
      v36 = v4 | v38 ^ v60;
      if( v4 < v60 )
        v36 += v58;
      _InterlockedCompareExchange64((volatile signed __int64 *)(v13 + 200), v36, v40);
    }
    v15 = v35 + v36;
    goto LABEL_9;
  }
  *(_QWORD *)&SpinCount[4] = 10000000i64;
  if( HalpTimerReferencePage )
  {
    if( (*(_DWORD *)(HalpPerformanceCounter + 224) & 0x10000) != 0 )
      v14 = *(_QWORD *)(HalpPerformanceCounter + 72)
          + (unsigned int)(*((_DWORD *)KeGetPcr() + 105) * *(_DWORD *)(HalpPerformanceCounter + 80));
    else
      v14 = *(_QWORD *)(HalpPerformanceCounter + 72);
    v15 = (((unsigned __int64)(*(__int64(__fastcall **)(__int64))(HalpPerformanceCounter + 112))(v14)
          * (unsigned __int128)*((unsigned __int64 *)HalpTimerReferencePage + 1)) >> 64)
        + KUSER_SHARED_DATA.QpcBias;
  }
  else
  {
    if( *(_DWORD *)(HalpPerformanceCounter + 220) == 64 )
    {
      HalpTimerGetInternalData((KDPC *)HalpPerformanceCounter, v2, v3, (PVOID)v4);
      v46 = (*(__int64(__fastcall **)(__int64))(v13 + 112))(v45);
      v47 = *(_QWORD *)(v13 + 208);
      v48 = v46;
    }
    else
    {
      do
      {
        v47 = *(_QWORD *)(v13 + 208);
        do
        {
          v49 = *(_QWORD *)(v13 + 200);
          HalpTimerGetInternalData((KDPC *)v13, v2, v3, (PVOID)v4);
          v51 = (*(__int64(__fastcall **)(__int64))(v13 + 112))(v50);
          _InterlockedOr(v64, 0);
          v52 = *(_QWORD *)(v13 + 200);
        }
        while( v49 != v52 );
      }
      while( v47 != *(_QWORD *)(v13 + 208) );
      v53 = *(_DWORD *)(v13 + 220);
      if( ((v49 ^ v51) & (1i64 << ((unsigned __int8)v53 - 1))) != 0 )
      {
        v54 = 1i64 << v53;
        v55 = -1i64;
        if( v53 != 64 )
          v55 = v54 - 1;
        v56 = v49 & v55;
        v48 = v51 | v49 ^ v56;
        if( v51 < v56 )
          v48 += v54;
        _InterlockedCompareExchange64((volatile signed __int64 *)(v13 + 200), v48, v52);
      }
      else
      {
        if( v53 == 64 )
          v57 = -1i64;
        else
          v57 = (1i64 << v53) - 1;
        v48 = v51 | v49 & ~v57;
      }
    }
    v15 = HalpTimerScaleCounter(v47 + v48, *(_QWORD *)(v13 + 192), 0x989680ui64);
  }
LABEL_9:
  if( v13 != HalpOriginalPerformanceCounter && HalpOriginalPerformanceCounter )
  {
    v37 = *(_QWORD *)(HalpOriginalPerformanceCounter + 192);
    if( *(_DWORD *)(HalpOriginalPerformanceCounter + 228) == 5 )
      v37 = 10000000i64;
    v15 = HalpTimerScaleCounter(v15, *(UINT64 *)&SpinCount[4], v37);
  }
  *((_QWORD *)&v16 + 1) = 0i64;
  if( v15 > KUSER_SHARED_DATA.BaselineSystemTimeQpc )
  {
    v68 = 0i64;
    v17 = v15 - KUSER_SHARED_DATA.BaselineSystemTimeQpc;
    if( KUSER_SHARED_DATA.QpcSystemTimeIncrementShift )
      v17 <<= KUSER_SHARED_DATA.QpcSystemTimeIncrementShift;
    v16 = v17 * (unsigned __int128)KUSER_SHARED_DATA.QpcSystemTimeIncrement;
    v68 = *((_QWORD *)&v16 + 1);
    *(_QWORD *)KiSystemTimeErrorAccumulator += v16;
    if( *(_QWORD *)KiSystemTimeErrorAccumulator < (unsigned __int64)v16 )
      v68 = ++*((_QWORD *)&v16 + 1);
  }
  v18 = *((_QWORD *)&v16 + 1) + *(_QWORD *)&KUSER_SHARED_DATA.SystemTime.LowPart;
  *((_QWORD *)&v16 + 1) = 0i64;
  if( v15 > KUSER_SHARED_DATA.BaselineInterruptTimeQpc )
  {
    v69 = 0i64;
    v19 = v15 - KUSER_SHARED_DATA.BaselineInterruptTimeQpc;
    if( KUSER_SHARED_DATA.QpcInterruptTimeIncrementShift )
      v19 <<= KUSER_SHARED_DATA.QpcInterruptTimeIncrementShift;
    v16 = v19 * (unsigned __int128)KUSER_SHARED_DATA.QpcInterruptTimeIncrement;
    v69 = *((_QWORD *)&v16 + 1);
    KiInterruptTimeErrorAccumulator += v16;
    if( KiInterruptTimeErrorAccumulator < (unsigned __int64)v16 )
      v69 = ++*((_QWORD *)&v16 + 1);
  }
  v20 = *(_QWORD *)&KUSER_SHARED_DATA.InterruptTime.LowPart + *((_QWORD *)&v16 + 1);
  KUSER_SHARED_DATA.SystemTime.High2Time = HIDWORD(v18);
  *(_QWORD *)&KUSER_SHARED_DATA.SystemTime.LowPart = v18;
  KUSER_SHARED_DATA.InterruptTime.High2Time = (*(_QWORD *)&KUSER_SHARED_DATA.InterruptTime.LowPart
                                             + *((_QWORD *)&v16 + 1)) >> 32;
  *(_QWORD *)&KUSER_SHARED_DATA.InterruptTime.LowPart += *((_QWORD *)&v16 + 1);
  KUSER_SHARED_DATA.BaselineSystemTimeQpc = v15;
  KUSER_SHARED_DATA.BaselineInterruptTimeQpc = v15;
  v21 = KUSER_SHARED_DATA.TickCountQuad;
  v22 = (EVENT_DESCRIPTOR *)((unsigned int)KiTickOffset - *((_QWORD *)&v16 + 1));
  if( (__int64)v22 <= 0 )
  {
    *((_QWORD *)&v16 + 1) = 1i64;
    v22 = (EVENT_DESCRIPTOR *)((char *)v22 + KeMaximumIncrement);
    if( (__int64)v22 <= 0 )
    {
      v43 = KeNumberProcessorsGroup0[2];
      v44 = (unsigned __int64)(((unsigned __int64)-(__int64)v22
                              * (unsigned __int128)(unsigned __int64)KiMaximumIncrementReciprocal) >> 64) >> v43;
      v22 = (EVENT_DESCRIPTOR *)((char *)v22 + (v44 + 1) * KeMaximumIncrement);
      *((_QWORD *)&v16 + 1) = v44 + 2;
    }
    v21 = *((_QWORD *)&v16 + 1) + KUSER_SHARED_DATA.TickCountQuad;
    KUSER_SHARED_DATA.TickCount.High2Time = (*((_QWORD *)&v16 + 1) + KUSER_SHARED_DATA.TickCountQuad) >> 32;
    KUSER_SHARED_DATA.TickCountQuad += *((_QWORD *)&v16 + 1);
  }
  KiTickOffset = (int)v22;
  ++KUSER_SHARED_DATA.TimeUpdateLock;
  v23 = KeGetCurrentPrcb();
  *(_DWORD *)SpinCount = 0;
  while( _interlockedbittestandset64((volatile signed __int32 *)&KiForceIdleLock, 0i64) )
  {
    do
      KeYieldProcessorEx((UINT64 *)SpinCount);
    while( KiForceIdleLock );
    v61 = *((_QWORD *)v23 + 4247);
    if( v61 && *((_BYTE *)v23 + 32) <= 1u )
    {
      v62 = *(_DWORD *)(v61 + 24) + 1;
      *(_DWORD *)(v61 + 24) = v62;
    }
  }
  if( KiForceIdleStartTime && v20 >= KiForceIdleStartTime && (_DWORD)KiForceIdleState == 2 )
  {
    KiSetForceIdleState((unsigned int)(KiForceIdleState - 1), *((INT64 *)&v16 + 1), v22);
    if( !*(&KiForceIdleStartDpc + 7) )
      WORD1(KiForceIdleStartDpc) = *((_DWORD *)CurrentPrcb + 9) + 1280;
    KiInsertQueueDpc((_KDPC *)&KiForceIdleStartDpc, 0i64, 0i64, 0i64, 0);
  }
  if( (((_DWORD)KiForceIdleState - 1) & 0xFFFFFFFD) == 0 )
    v7 = 1;
  _InterlockedAnd64(&KiForceIdleLock, 0i64);
  if( v10 )
    _enable();
  if( KeMinimumIncrement - 1 + (int)v20 - (int)KiLastNonHrTimerExpiration >= (unsigned int)KeNonHrTimeIncrement )
    KiLastNonHrTimerExpiration = (PVOID)v20;
  if( KeMinimumIncrement - 1 + (int)v20 - (int)KiLastPseudoHrTimerExpiration >= (unsigned int)KePseudoHrTimeIncrement )
    KiLastPseudoHrTimerExpiration = v20;
  if( v21 != TickCountQuad && !--*(_DWORD *)KiBalanceSetManagerCount )
  {
    *(_DWORD *)KiBalanceSetManagerCount = KiBalanceSetManagerPeriod;
    KiInsertQueueDpc((_KDPC *)&KiBalanceSetManagerPeriodicDpc, 0i64, 0i64, 0i64, 0);
  }
  PoExecuteIdleCheck(v20);
  if( !v7 )
    PoExecutePerfCheck();
  v24 = v20 >> 18;
  if( KiGroupSchedulingEnabled && v21 > KiGenerationEndTick )
  {
    v8 = 1;
    KiGenerationEndTick += *(unsigned int *)KiGenerationTicks;
  }
  if( (unsigned int)KeNumberProcessors_0 > 1 )
  {
    KiForwardTick(CurrentPrcb, (unsigned int)KeNumberProcessors_0, v24, v8, &result);
    Count = KiClockCheckPending[0];
    if( (unsigned int)KiClockCheckPending[0] < result.Count )
    {
      p_result = &result;
    }
    else
    {
      p_result = (_KAFFINITY_EX *)KiClockCheckPending;
      Count = result.Count;
    }
    v27 = 0i64;
    word_140C110D2 = 20;
    KiClockCheckPending[0] = p_result->Count;
    v28 = 0;
    if( Count )
    {
      v29 = 0i64;
      v28 = Count;
      v27 = Count;
      do
      {
        *(_QWORD *)&KiClockCheckPending[v29 / 2 + 4] |= result.Bitmap[v29 / 8];
        v29 += 8i64;
        --v27;
      }
      while( v27 );
    }
    for( ; v28 < p_result->Count; *(_QWORD *)&KiClockCheckPending[4 * v30 + 4] = p_result->Bitmap[v30] )
      v30 = v28++;
    for( dword_140C110D4 = v27; v28 < (unsigned __int16)word_140C110D2; *(_QWORD *)&KiClockCheckPending[4 * v63 + 4] = v27 )
      v63 = v28++;
  }
  return KiUpdateRunTime(v66, v65);
}

Referenced by:

KeClockInterruptNotify