diff options
| author | JMC47 <JMC4789@gmail.com> | 2025-08-28 13:58:26 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-28 13:58:26 -0400 |
| commit | e0c72cd963bbde29f01fa33b06c22f7dff871e5d (patch) | |
| tree | 3cbd60189a9aa5aa6174ac3ad7cb91027b6b481a /Source/Core/Common/Timer.cpp | |
| parent | dce27fb58a9f071c707ad31085611cc3d72bad33 (diff) | |
| parent | 81ebf45c9ba652083446929eea551dc8ba2f05be (diff) | |
Merge pull request #13825 from jordan-woyak/dont-count-playtime-while-suspended
Common/Timer: Add a SteadyAwakeClock class to make play time tracking ignore time while suspended.
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 |
