summaryrefslogtreecommitdiffstats
path: root/src/common/steady_clock.cpp
diff options
context:
space:
mode:
authorliamwhite <liamwhite@users.noreply.github.com>2023-03-07 16:54:13 +0100
committerGitHub <noreply@github.com>2023-03-07 16:54:13 +0100
commita7792e5ff83523142230951ac7eacbd7685dc40b (patch)
treea7531c65e2ddec1122fc071d44c8106c48352ce3 /src/common/steady_clock.cpp
parentMerge pull request #9890 from Kelebek1/reverb_fix (diff)
parentnative_clock: Round RDTSC frequency to the nearest 1000 (diff)
downloadyuzu-a7792e5ff83523142230951ac7eacbd7685dc40b.tar
yuzu-a7792e5ff83523142230951ac7eacbd7685dc40b.tar.gz
yuzu-a7792e5ff83523142230951ac7eacbd7685dc40b.tar.bz2
yuzu-a7792e5ff83523142230951ac7eacbd7685dc40b.tar.lz
yuzu-a7792e5ff83523142230951ac7eacbd7685dc40b.tar.xz
yuzu-a7792e5ff83523142230951ac7eacbd7685dc40b.tar.zst
yuzu-a7792e5ff83523142230951ac7eacbd7685dc40b.zip
Diffstat (limited to '')
-rw-r--r--src/common/steady_clock.cpp56
1 files changed, 56 insertions, 0 deletions
diff --git a/src/common/steady_clock.cpp b/src/common/steady_clock.cpp
new file mode 100644
index 000000000..0d5908aa7
--- /dev/null
+++ b/src/common/steady_clock.cpp
@@ -0,0 +1,56 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#if defined(_WIN32)
+#include <windows.h>
+#else
+#include <time.h>
+#endif
+
+#include "common/steady_clock.h"
+
+namespace Common {
+
+#ifdef _WIN32
+static s64 WindowsQueryPerformanceFrequency() {
+ LARGE_INTEGER frequency;
+ QueryPerformanceFrequency(&frequency);
+ return frequency.QuadPart;
+}
+
+static s64 WindowsQueryPerformanceCounter() {
+ LARGE_INTEGER counter;
+ QueryPerformanceCounter(&counter);
+ return counter.QuadPart;
+}
+#endif
+
+SteadyClock::time_point SteadyClock::Now() noexcept {
+#if defined(_WIN32)
+ static const auto freq = WindowsQueryPerformanceFrequency();
+ const auto counter = WindowsQueryPerformanceCounter();
+
+ // 10 MHz is a very common QPC frequency on modern PCs.
+ // Optimizing for this specific frequency can double the performance of
+ // this function by avoiding the expensive frequency conversion path.
+ static constexpr s64 TenMHz = 10'000'000;
+
+ if (freq == TenMHz) [[likely]] {
+ static_assert(period::den % TenMHz == 0);
+ static constexpr s64 Multiplier = period::den / TenMHz;
+ return time_point{duration{counter * Multiplier}};
+ }
+
+ const auto whole = (counter / freq) * period::den;
+ const auto part = (counter % freq) * period::den / freq;
+ return time_point{duration{whole + part}};
+#elif defined(__APPLE__)
+ return time_point{duration{clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW)}};
+#else
+ timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ return time_point{std::chrono::seconds{ts.tv_sec} + std::chrono::nanoseconds{ts.tv_nsec}};
+#endif
+}
+
+}; // namespace Common