KiUpdateTime

VOID __stdcall KiUpdateTime(CHAR ProcessorMode, UINT8 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; 
  INT64 v13; 
  __int64 v14; 
  UINT64 v15; 
  unsigned __int128 v16; 
  UINT64 v17; 
  __int64 v18; 
  UINT64 v19; 
  UINT64 v20; 
  volatile unsigned __int64 v21; 
  NPTEXTMETRIC *v22; 
  struct _KPRCB *v23; 
  UINT64 v24; 
  unsigned __int16 Count; 
  _KAFFINITY_EX *p_TickMask; 
  unsigned __int64 v27; 
  unsigned __int16 v28; 
  __int64 v29; 
  __int64 v30; 
  bool v31; 
  __int64 v32; 
  __int64 v33; 
  __int64 v34; 
  signed __int64 v35; 
  UINT64 v36; 
  __int64 v37; 
  __int64 v38; 
  signed __int64 v39; 
  int v40; 
  __int64 v41; 
  volatile CCHAR v42; 
  unsigned __int64 v43; 
  __int64 v44; 
  __int64 v45; 
  __int64 v46; 
  signed __int64 v47; 
  __int64 v48; 
  __int64 v49; 
  unsigned __int64 v50; 
  signed __int64 v51; 
  int v52; 
  __int64 v53; 
  __int64 v54; 
  unsigned __int64 v55; 
  __int64 v56; 
  __int64 v57; 
  __int64 v58; 
  unsigned __int64 v59; 
  _DWORD *SchedulerAssist; 
  int v61; 
  __int64 v62; 
  signed __int32 v63[8]; 
  UINT8 v64; 
  unsigned __int8 v65; 
  char SpinCount[12]; 
  __int64 v67; 
  __int64 v68; 
  _KAFFINITY_EX TickMask; 
  int v70; 

  v64 = PreviousIrql;
  v65 = ProcessorMode;
  memset(&TickMask, 0i64, sizeof(TickMask));
  CurrentPrcb = KeGetCurrentPrcb();
  v6 = v70;
  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 )
  {
    v31 = *(_DWORD *)(HalpPerformanceCounter + 220) == 64;
    *(_QWORD *)&SpinCount[4] = *(_QWORD *)(HalpPerformanceCounter + 192);
    if( v31 )
    {
      HalpTimerGetInternalData((_KDPC *)HalpPerformanceCounter, v2, v3, (PVOID)v4);
      v33 = (*(__int64(__fastcall **)(__int64))(v13 + 112))(v32);
      v34 = *(_QWORD *)(v13 + 208);
      v35 = v33;
    }
    else
    {
      do
      {
        v34 = *(_QWORD *)(v13 + 208);
        do
        {
          v37 = *(_QWORD *)(v13 + 200);
          HalpTimerGetInternalData((_KDPC *)v13, v2, v3, (PVOID)v4);
          v4 = (*(__int64(__fastcall **)(__int64))(v13 + 112))(v38);
          _InterlockedOr(v63, 0);
          v39 = *(_QWORD *)(v13 + 200);
        }
        while( v37 != v39 );
      }
      while( v34 != *(_QWORD *)(v13 + 208) );
      v40 = *(_DWORD *)(v13 + 220);
      if( ((v37 ^ v4) & (1i64 << ((unsigned __int8)v40 - 1))) == 0 )
      {
        if( v40 == 64 )
          v41 = -1i64;
        else
          v41 = (1i64 << v40) - 1;
        v15 = v34 + (v4 | v37 & ~v41);
        goto LABEL_9;
      }
      v57 = 1i64 << v40;
      v58 = -1i64;
      if( v40 != 64 )
        v58 = v57 - 1;
      v59 = v37 & v58;
      v35 = v4 | v37 ^ v59;
      if( v4 < v59 )
        v35 += v57;
      _InterlockedCompareExchange64((volatile signed __int64 *)(v13 + 200), v35, v39);
    }
    v15 = v34 + v35;
    goto LABEL_9;
  }
  *(_QWORD *)&SpinCount[4] = 10000000i64;
  if( HalpTimerReferencePage )
  {
    if( (*(_DWORD *)(HalpPerformanceCounter + 224) & 0x10000) != 0 )
      v14 = *(_QWORD *)(HalpPerformanceCounter + 72)
          + KeGetPcr()->Prcb.Number * *(_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);
      v45 = (*(__int64(__fastcall **)(__int64))(v13 + 112))(v44);
      v46 = *(_QWORD *)(v13 + 208);
      v47 = v45;
    }
    else
    {
      do
      {
        v46 = *(_QWORD *)(v13 + 208);
        do
        {
          v48 = *(_QWORD *)(v13 + 200);
          HalpTimerGetInternalData((_KDPC *)v13, v2, v3, (PVOID)v4);
          v50 = (*(__int64(__fastcall **)(__int64))(v13 + 112))(v49);
          _InterlockedOr(v63, 0);
          v51 = *(_QWORD *)(v13 + 200);
        }
        while( v48 != v51 );
      }
      while( v46 != *(_QWORD *)(v13 + 208) );
      v52 = *(_DWORD *)(v13 + 220);
      if( ((v48 ^ v50) & (1i64 << ((unsigned __int8)v52 - 1))) != 0 )
      {
        v53 = 1i64 << v52;
        v54 = -1i64;
        if( v52 != 64 )
          v54 = v53 - 1;
        v55 = v48 & v54;
        v47 = v50 | v48 ^ v55;
        if( v50 < v55 )
          v47 += v53;
        _InterlockedCompareExchange64((volatile signed __int64 *)(v13 + 200), v47, v51);
      }
      else
      {
        if( v52 == 64 )
          v56 = -1i64;
        else
          v56 = (1i64 << v52) - 1;
        v47 = v50 | v48 & ~v56;
      }
    }
    v15 = HalpTimerScaleCounter(v46 + v47, *(_QWORD *)(v13 + 192), 0x989680ui64);
  }
LABEL_9:
  if( v13 != HalpOriginalPerformanceCounter && HalpOriginalPerformanceCounter )
  {
    v36 = *(_QWORD *)(HalpOriginalPerformanceCounter + 192);
    if( *(_DWORD *)(HalpOriginalPerformanceCounter + 228) == 5 )
      v36 = 10000000i64;
    v15 = HalpTimerScaleCounter(v15, *(UINT64 *)&SpinCount[4], v36);
  }
  *((_QWORD *)&v16 + 1) = 0i64;
  if( v15 > KUSER_SHARED_DATA.BaselineSystemTimeQpc )
  {
    v67 = 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;
    v67 = *((_QWORD *)&v16 + 1);
    qword_140C50468 += v16;
    if( qword_140C50468 < (unsigned __int64)v16 )
      v67 = ++*((_QWORD *)&v16 + 1);
  }
  v18 = *((_QWORD *)&v16 + 1) + *(_QWORD *)&KUSER_SHARED_DATA.SystemTime.LowPart;
  *((_QWORD *)&v16 + 1) = 0i64;
  if( v15 > KUSER_SHARED_DATA.BaselineInterruptTimeQpc )
  {
    v68 = 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;
    v68 = *((_QWORD *)&v16 + 1);
    qword_140C50398 += v16;
    if( qword_140C50398 < (unsigned __int64)v16 )
      v68 = ++*((_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 = (NPTEXTMETRIC *)((unsigned int)KiTickOffset - *((_QWORD *)&v16 + 1));
  if( (__int64)v22 <= 0 )
  {
    *((_QWORD *)&v16 + 1) = 1i64;
    v22 = (NPTEXTMETRIC *)((char *)v22 + (unsigned int)KeMaximumIncrement);
    if( (__int64)v22 <= 0 )
    {
      v42 = KeNumberProcessorsGroup0[2];
      v43 = (unsigned __int64)(((unsigned __int64)-(__int64)v22
                              * (unsigned __int128)(unsigned __int64)KiMaximumIncrementReciprocal) >> 64) >> v42;
      v22 = (NPTEXTMETRIC *)((char *)v22 + (v43 + 1) * (unsigned int)KeMaximumIncrement);
      *((_QWORD *)&v16 + 1) = v43 + 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((_DWORD *)&KiSwapEvent + 42, 0i64) )
  {
    do
      KeYieldProcessorEx((UINT64 *)SpinCount);
    while( *(&KiSwapEvent + 21) );
    SchedulerAssist = v23->SchedulerAssist;
    if( SchedulerAssist && v23->NestingLevel <= 1u )
    {
      v61 = SchedulerAssist[6] + 1;
      SchedulerAssist[6] = v61;
    }
  }
  if( *(&KiSwapEvent + 20) && v20 >= *(&KiSwapEvent + 20) && (_DWORD)KiForceIdleState == 2 )
  {
    KiSetForceIdleState((unsigned int)(KiForceIdleState - 1), *((INT64 *)&v16 + 1), v22);
    if( !*(&KiSwapEvent + 31) )
      *(&KiSwapEvent + 97) = CurrentPrcb->Number + 1280;
    KiInsertQueueDpc((_KDPC *)&KiSwapEvent + 3, 0i64, 0i64, 0i64, 0);
  }
  if( (((_DWORD)KiForceIdleState - 1) & 0xFFFFFFFD) == 0 )
    v7 = 1;
  _InterlockedAnd64((_QWORD *)&KiSwapEvent + 21, 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 && !--*(&KiSwapEvent + 80) )
  {
    *(&KiSwapEvent + 80) = KiBalanceSetManagerPeriod;
    KiInsertQueueDpc((_KDPC *)&KiSwapEvent + 4, 0i64, 0i64, 0i64, 0);
  }
  PoExecuteIdleCheck(v20);
  if( !v7 )
    PoExecutePerfCheck();
  v24 = v20 >> 18;
  if( KiGroupSchedulingEnabled && v21 > *(&KiSwapEvent + 41) )
  {
    v8 = 1;
    *(&KiSwapEvent + 41) += (unsigned int)KiGenerationTicks;
  }
  if( (unsigned int)KeNumberProcessors_0 > 1 )
  {
    KiForwardTick(CurrentPrcb, (unsigned int)KeNumberProcessors_0, v24, v8, &TickMask);
    Count = KiClockCheckPending.Count;
    if( KiClockCheckPending.Count < TickMask.Count )
    {
      p_TickMask = &TickMask;
    }
    else
    {
      p_TickMask = &KiClockCheckPending;
      Count = TickMask.Count;
    }
    v27 = 0i64;
    KiClockCheckPending.Size = 20;
    KiClockCheckPending.Count = p_TickMask->Count;
    v28 = 0;
    if( Count )
    {
      v29 = 0i64;
      v28 = Count;
      v27 = Count;
      do
      {
        KiClockCheckPending.Bitmap[v29] |= TickMask.Bitmap[v29];
        ++v29;
        --v27;
      }
      while( v27 );
    }
    for( ; v28 < p_TickMask->Count; KiClockCheckPending.Bitmap[v30] = p_TickMask->Bitmap[v30] )
      v30 = v28++;
    for( KiClockCheckPending.Reserved = v27; v28 < KiClockCheckPending.Size; KiClockCheckPending.Bitmap[v62] = v27 )
      v62 = v28++;
  }
  KiUpdateRunTime(v65, v64);
}

Referenced by:

KeClockInterruptNotify