From aee9f588d72e1b9614b3f38c068aae9f2ffb0672 Mon Sep 17 00:00:00 2001 From: themuffinator Date: Fri, 21 Nov 2025 17:12:36 +0000 Subject: [PATCH] Handle QueryPerformanceCounter failure with fallback --- src/windows/system.cpp | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/src/windows/system.cpp b/src/windows/system.cpp index 2ea6413..6d25fe6 100644 --- a/src/windows/system.cpp +++ b/src/windows/system.cpp @@ -1438,11 +1438,42 @@ bool Sys_IsMainThread(void) return GetCurrentThreadId() == main_thread_id; } +/* +============= +Sys_Milliseconds + +Returns milliseconds since startup using a monotonic clock. +Falls back to a lower-resolution timer if high-resolution queries fail. +============= +*/ unsigned Sys_Milliseconds(void) { - LARGE_INTEGER tm; - QueryPerformanceCounter(&tm); - return tm.QuadPart * 1000ULL / timer_freq.QuadPart; + static bool qpc_available = true; + static DWORD fallback_base = 0; + static unsigned last_msec = 0; + + if (qpc_available) { + LARGE_INTEGER tm; + if (QueryPerformanceCounter(&tm)) { + unsigned msec = static_cast(tm.QuadPart * 1000ULL / timer_freq.QuadPart); + if (msec < last_msec) + msec = last_msec; + last_msec = msec; + return msec; + } + + Sys_Printf("QueryPerformanceCounter failed; falling back to timeGetTime (low resolution).\n"); + qpc_available = false; + fallback_base = timeGetTime(); + } + + DWORD current = timeGetTime(); + unsigned msec = current - fallback_base; + if (msec < last_msec) + msec = last_msec; + else + last_msec = msec; + return msec; } void Sys_AddDefaultConfig(void)