diff options
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 |
