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