From c3fbc8d2fe2ff423d774ed3886fc8391c730f637 Mon Sep 17 00:00:00 2001 From: Morph <39850852+Morph1984@users.noreply.github.com> Date: Sun, 2 Jul 2023 15:05:35 -0400 Subject: [PATCH] core_timing: Remove GetCurrentTimerResolution in CoreTiming loop Other programs may change this value, but if thousands of syscalls in this loop is undesirable, then we can just set this once. --- src/core/core_timing.cpp | 9 ++++++--- src/core/core_timing.h | 8 ++++++++ src/yuzu/main.cpp | 2 ++ src/yuzu_cmd/yuzu.cpp | 8 ++++++-- 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index 4f0a3f8ea..e6112a3c9 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp @@ -253,9 +253,6 @@ void CoreTiming::ThreadLoop() { auto wait_time = *next_time - GetGlobalTimeNs().count(); if (wait_time > 0) { #ifdef _WIN32 - const auto timer_resolution_ns = - Common::Windows::GetCurrentTimerResolution().count(); - while (!paused && !event.IsSet() && wait_time > 0) { wait_time = *next_time - GetGlobalTimeNs().count(); @@ -316,4 +313,10 @@ std::chrono::microseconds CoreTiming::GetGlobalTimeUs() const { return std::chrono::microseconds{Common::WallClock::CPUTickToUS(cpu_ticks)}; } +#ifdef _WIN32 +void CoreTiming::SetTimerResolutionNs(std::chrono::nanoseconds ns) { + timer_resolution_ns = ns.count(); +} +#endif + } // namespace Core::Timing diff --git a/src/core/core_timing.h b/src/core/core_timing.h index 10db1de55..5bca1c78d 100644 --- a/src/core/core_timing.h +++ b/src/core/core_timing.h @@ -131,6 +131,10 @@ public: /// Checks for events manually and returns time in nanoseconds for next event, threadsafe. std::optional Advance(); +#ifdef _WIN32 + void SetTimerResolutionNs(std::chrono::nanoseconds ns); +#endif + private: struct Event; @@ -143,6 +147,10 @@ private: s64 global_timer = 0; +#ifdef _WIN32 + s64 timer_resolution_ns; +#endif + // The queue is a min-heap using std::make_heap/push_heap/pop_heap. // We don't use std::priority_queue because we need to be able to serialize, unserialize and // erase arbitrary events (RemoveEvent()) regardless of the queue order. These aren't diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index e8418b302..fea5eb614 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -101,6 +101,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual #include "common/settings.h" #include "common/telemetry.h" #include "core/core.h" +#include "core/core_timing.h" #include "core/crypto/key_manager.h" #include "core/file_sys/card_image.h" #include "core/file_sys/common_funcs.h" @@ -389,6 +390,7 @@ GMainWindow::GMainWindow(std::unique_ptr config_, bool has_broken_vulkan std::chrono::duration_cast>( Common::Windows::SetCurrentTimerResolutionToMaximum()) .count()); + system->CoreTiming().SetTimerResolutionNs(Common::Windows::GetCurrentTimerResolution()); #endif UpdateWindowTitle(); diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index 7b6d49c63..d0433ffc6 100644 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp @@ -21,6 +21,7 @@ #include "common/string_util.h" #include "common/telemetry.h" #include "core/core.h" +#include "core/core_timing.h" #include "core/cpu_manager.h" #include "core/crypto/key_manager.h" #include "core/file_sys/registered_cache.h" @@ -316,8 +317,6 @@ int main(int argc, char** argv) { #ifdef _WIN32 LocalFree(argv_w); - - Common::Windows::SetCurrentTimerResolutionToMaximum(); #endif MicroProfileOnThreadCreate("EmuThread"); @@ -351,6 +350,11 @@ int main(int argc, char** argv) { break; } +#ifdef _WIN32 + Common::Windows::SetCurrentTimerResolutionToMaximum(); + system.CoreTiming().SetTimerResolutionNs(Common::Windows::GetCurrentTimerResolution()); +#endif + system.SetContentProvider(std::make_unique()); system.SetFilesystem(std::make_shared()); system.GetFileSystemController().CreateFactories(*system.GetFilesystem());