diff options
| author | Jordan Woyak <jordan.woyak@gmail.com> | 2025-07-23 23:51:45 -0500 |
|---|---|---|
| committer | Jordan Woyak <jordan.woyak@gmail.com> | 2025-07-24 23:56:10 -0500 |
| commit | 62c773ac7517feb9e12b4edb7fda5145b41a34d4 (patch) | |
| tree | 2da49436d666a10d630a5447aabf0ce8d81dcb13 /Source/Core/Common/Timer.cpp | |
| parent | 64d4c4020cf444d5afea708b38d1b363e532c7ba (diff) | |
Common/Timer: Add a SteadyAwakeClock class which counts non-suspended system running time.
Diffstat (limited to 'Source/Core/Common/Timer.cpp')
| -rw-r--r-- | Source/Core/Common/Timer.cpp | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/Source/Core/Common/Timer.cpp b/Source/Core/Common/Timer.cpp index 0a23080c6f..0e260b833c 100644 --- a/Source/Core/Common/Timer.cpp +++ b/Source/Core/Common/Timer.cpp @@ -5,6 +5,7 @@ #include <chrono> #include <thread> +#include "Common/CommonFuncs.h" #ifdef _WIN32 #include <Windows.h> @@ -194,4 +195,37 @@ void PrecisionTimer::SleepUntil(Clock::time_point target) } } +// Results are appropriately slewed on Linux, but not on Windows, macOS, or FreeBSD. +// Clocks with that functionality seem to not be available there. +auto SteadyAwakeClock::now() -> time_point +{ +#if defined(_WIN32) + // The count is system time "in units of 100 nanoseconds". + using InterruptDuration = std::chrono::duration<ULONGLONG, std::ratio<100, std::nano::den>::type>; + + ULONGLONG interrupt_time{}; + if (!QueryUnbiasedInterruptTime(&interrupt_time)) + ERROR_LOG_FMT(COMMON, "QueryUnbiasedInterruptTime"); + + return time_point{InterruptDuration{interrupt_time}}; +#else + // Note that Linux's CLOCK_MONOTONIC "does not count time that the system is suspended". + // This is in contrast to the behavior on macOS and FreeBSD. + static constexpr auto clock_id = +#if defined(__linux__) + CLOCK_MONOTONIC; +#elif defined(__APPLE__) + CLOCK_UPTIME_RAW; +#else + CLOCK_UPTIME; +#endif + + timespec ts{}; + if (clock_gettime(clock_id, &ts) != 0) + ERROR_LOG_FMT(COMMON, "clock_gettime: {}", LastStrerrorString()); + + return time_point{std::chrono::seconds{ts.tv_sec} + std::chrono::nanoseconds{ts.tv_nsec}}; +#endif +} + } // Namespace Common |
