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