Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 34 additions & 3 deletions src/windows/system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<unsigned>(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)
Comment on lines +1465 to +1472

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Fallback timer never advances after QPC failure

When QueryPerformanceCounter fails, fallback_base is set to the current timeGetTime() while last_msec still holds the absolute QPC-derived milliseconds since boot. The very next call computes msec = current - fallback_base (near zero) and clamps it to last_msec, but fallback_base is not offset by that value. The result is that Sys_Milliseconds returns a constant last_msec until timeGetTime() has advanced by at least that many milliseconds—potentially freezing the timer for many minutes or hours after the fallback is triggered. Consider seeding fallback_base so timeGetTime() continues from last_msec immediately.

Useful? React with 👍 / 👎.

msec = last_msec;
else
last_msec = msec;
return msec;
}

void Sys_AddDefaultConfig(void)
Expand Down