mirror of
https://github.com/SWG-Source/src.git
synced 2026-07-31 00:15:55 -04:00
Back QueryPerformanceCounter with a monotonic clock
The linux shim sampled gettimeofday(), which reports CLOCK_REALTIME and can be slewed or stepped backwards by time synchronisation. Clock::update() subtracts successive samples to derive frame time, so a backwards step produced a negative elapsed time, which AlterScheduler then reported as "no forward time movement" once per affected frame. Use clock_gettime(CLOCK_MONOTONIC) and keep microsecond units so the value still matches QueryPerformanceFrequency(). Falls back to gettimeofday() if the call fails. All getFrameStartTimeMs() consumers compare values relatively, so nothing depends on the previous epoch-based origin.
This commit is contained in:
@@ -27,10 +27,23 @@ char* _itoa(int value, char* stringOut, int radix)
|
||||
|
||||
bool QueryPerformanceCounter(__int64* time)
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, nullptr);
|
||||
*time = static_cast<LARGE_INTEGER>(tv.tv_sec);
|
||||
*time = (*time * 1000000) + static_cast<LARGE_INTEGER>(tv.tv_usec);
|
||||
// Must be monotonic. gettimeofday() reports CLOCK_REALTIME, which NTP can
|
||||
// slew or step backwards; callers subtract successive samples to derive
|
||||
// frame time, so a backwards step produced negative elapsed times (see
|
||||
// AlterScheduler "no forward time movement"). CLOCK_MONOTONIC never goes
|
||||
// backwards. Units stay microseconds to match QueryPerformanceFrequency().
|
||||
struct timespec ts;
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0)
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, nullptr);
|
||||
*time = static_cast<LARGE_INTEGER>(tv.tv_sec);
|
||||
*time = (*time * 1000000) + static_cast<LARGE_INTEGER>(tv.tv_usec);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
*time = static_cast<LARGE_INTEGER>(ts.tv_sec);
|
||||
*time = (*time * 1000000) + static_cast<LARGE_INTEGER>(ts.tv_nsec / 1000);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user