summaryrefslogtreecommitdiff
path: root/Source/Core/Common/Timer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/Common/Timer.cpp')
-rw-r--r--Source/Core/Common/Timer.cpp34
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