diff options
| -rw-r--r-- | src/common/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/common/steady_clock.cpp | 56 | ||||
| -rw-r--r-- | src/common/steady_clock.h | 23 |
3 files changed, 81 insertions, 0 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 56b247ac4..9f5d4c265 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt | |||
| @@ -113,6 +113,8 @@ add_library(common STATIC | |||
| 113 | socket_types.h | 113 | socket_types.h |
| 114 | spin_lock.cpp | 114 | spin_lock.cpp |
| 115 | spin_lock.h | 115 | spin_lock.h |
| 116 | steady_clock.cpp | ||
| 117 | steady_clock.h | ||
| 116 | stream.cpp | 118 | stream.cpp |
| 117 | stream.h | 119 | stream.h |
| 118 | string_util.cpp | 120 | string_util.cpp |
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 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #if defined(_WIN32) | ||
| 5 | #include <windows.h> | ||
| 6 | #else | ||
| 7 | #include <time.h> | ||
| 8 | #endif | ||
| 9 | |||
| 10 | #include "common/steady_clock.h" | ||
| 11 | |||
| 12 | namespace Common { | ||
| 13 | |||
| 14 | #ifdef _WIN32 | ||
| 15 | static s64 WindowsQueryPerformanceFrequency() { | ||
| 16 | LARGE_INTEGER frequency; | ||
| 17 | QueryPerformanceFrequency(&frequency); | ||
| 18 | return frequency.QuadPart; | ||
| 19 | } | ||
| 20 | |||
| 21 | static s64 WindowsQueryPerformanceCounter() { | ||
| 22 | LARGE_INTEGER counter; | ||
| 23 | QueryPerformanceCounter(&counter); | ||
| 24 | return counter.QuadPart; | ||
| 25 | } | ||
| 26 | #endif | ||
| 27 | |||
| 28 | SteadyClock::time_point SteadyClock::Now() noexcept { | ||
| 29 | #if defined(_WIN32) | ||
| 30 | static const auto freq = WindowsQueryPerformanceFrequency(); | ||
| 31 | const auto counter = WindowsQueryPerformanceCounter(); | ||
| 32 | |||
| 33 | // 10 MHz is a very common QPC frequency on modern PCs. | ||
| 34 | // Optimizing for this specific frequency can double the performance of | ||
| 35 | // this function by avoiding the expensive frequency conversion path. | ||
| 36 | static constexpr s64 TenMHz = 10'000'000; | ||
| 37 | |||
| 38 | if (freq == TenMHz) [[likely]] { | ||
| 39 | static_assert(period::den % TenMHz == 0); | ||
| 40 | static constexpr s64 Multiplier = period::den / TenMHz; | ||
| 41 | return time_point{duration{counter * Multiplier}}; | ||
| 42 | } | ||
| 43 | |||
| 44 | const auto whole = (counter / freq) * period::den; | ||
| 45 | const auto part = (counter % freq) * period::den / freq; | ||
| 46 | return time_point{duration{whole + part}}; | ||
| 47 | #elif defined(__APPLE__) | ||
| 48 | return time_point{duration{clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW)}}; | ||
| 49 | #else | ||
| 50 | timespec ts; | ||
| 51 | clock_gettime(CLOCK_MONOTONIC, &ts); | ||
| 52 | return time_point{std::chrono::seconds{ts.tv_sec} + std::chrono::nanoseconds{ts.tv_nsec}}; | ||
| 53 | #endif | ||
| 54 | } | ||
| 55 | |||
| 56 | }; // namespace Common | ||
diff --git a/src/common/steady_clock.h b/src/common/steady_clock.h new file mode 100644 index 000000000..9497cf865 --- /dev/null +++ b/src/common/steady_clock.h | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include <chrono> | ||
| 7 | |||
| 8 | #include "common/common_types.h" | ||
| 9 | |||
| 10 | namespace Common { | ||
| 11 | |||
| 12 | struct SteadyClock { | ||
| 13 | using rep = s64; | ||
| 14 | using period = std::nano; | ||
| 15 | using duration = std::chrono::nanoseconds; | ||
| 16 | using time_point = std::chrono::time_point<SteadyClock>; | ||
| 17 | |||
| 18 | static constexpr bool is_steady = true; | ||
| 19 | |||
| 20 | [[nodiscard]] static time_point Now() noexcept; | ||
| 21 | }; | ||
| 22 | |||
| 23 | } // namespace Common | ||