NtGetTickCount64 - NtDoc

Native API online documentation, based on the System Informer (formerly Process Hacker) phnt headers
#ifndef _NTEXAPI_H
#if (PHNT_MODE != PHNT_MODE_KERNEL)

/**
 * The NtGetTickCount64 routine retrieves the number of milliseconds that have elapsed since the system was started.
 *
 * \return ULONGLONG The return value is the number of milliseconds that have elapsed since the system was started.
 * \remarks The resolution of the NtGetTickCount64 function is limited to the resolution of the system timer,
 * which is typically in the range of 10 milliseconds to 16 milliseconds. The resolution of the NtGetTickCount64
 * function is not affected by adjustments made by the GetSystemTimeAdjustment function.
 * \see https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-gettickcount64
 */
FORCEINLINE
ULONGLONG
NtGetTickCount64(
    VOID
    )
{
    ULARGE_INTEGER tickCount;

#ifdef _WIN64

    tickCount.QuadPart = USER_SHARED_DATA->TickCountQuad;

#else

    while (TRUE)
    {
        // ARM64 builds default to /volatile:iso, where volatile loads have no ordering guarantee
        // and the CPU can reorder them. Without acquire semantics it could read High2Time or LowPart
        // before High1Time, and a torn value could pass the check because a stale High1Time would
        // still match High2Time. The window is rare, but it exists. The kernel writes High2Time,
        // LowPart, then High1Time, so read High1Time, LowPart, then High2Time with acquire ordering.
        tickCount.HighPart = (ULONG)ReadAcquire(&USER_SHARED_DATA->TickCount.High1Time);
        tickCount.LowPart = (ULONG)ReadAcquire((volatile LONG*)&USER_SHARED_DATA->TickCount.LowPart);

        if (tickCount.HighPart == (ULONG)ReadNoFence(&USER_SHARED_DATA->TickCount.High2Time))
            break;

        YieldProcessor();
    }

#endif

    return (UInt32x32To64(tickCount.LowPart, USER_SHARED_DATA->TickCountMultiplier) >> 24) +
        (UInt32x32To64(tickCount.HighPart, USER_SHARED_DATA->TickCountMultiplier) << 8);
}

#endif
#endif

View code on GitHub

NtDoc

No description available.