From 7c32cf03a1ce2a88b5bda041a5aebc8405fe634d Mon Sep 17 00:00:00 2001 From: lizzie Date: Sat, 30 May 2026 21:59:10 +0200 Subject: [core/core_timing] better MWAITX and WAITPKG delays (#3984) This implements MWAITX and WAITPKG extensions (umonitor, mwait) for CPUs that support them. Reduces wait times and bypasses the timing stuff from the OS that is slow (windows notably). generally it should answer within 0.2 to 0.5 microsecs (since most requests wait for that long). Also does a general rework of static ctors and stuff Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3984 Reviewed-by: MaranBr Reviewed-by: crueter --- src/core/core_timing.cpp | 38 ++++++++++---------------------------- 1 file changed, 10 insertions(+), 28 deletions(-) (limited to 'src/core/core_timing.cpp') diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index 6738a0d73d..3e4e7bdc68 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp @@ -8,15 +8,13 @@ #include #include #include +#include "common/cpu_features.h" +#include "common/cpu_features.h" #ifdef _WIN32 #include "common/windows/timer_resolution.h" #endif -#ifdef ARCHITECTURE_x86_64 -#include "common/x64/cpu_wait.h" -#endif - #include "common/settings.h" #include "core/core_timing.h" #include "core/hardware_properties.h" @@ -47,8 +45,7 @@ struct CoreTiming::Event { } }; -CoreTiming::CoreTiming() : clock{Common::CreateOptimalClock()} {} - +CoreTiming::CoreTiming() = default; CoreTiming::~CoreTiming() { Reset(); } @@ -64,31 +61,16 @@ void CoreTiming::Initialize(std::function&& on_thread_init_) { Common::SetCurrentThreadPriority(Common::ThreadPriority::High); on_thread_init(); has_started = true; + + // base frequency in MHz: 1ns (10^-9) = 1GHz (10^9) while (!stop_token.stop_requested()) { while (!paused && !stop_token.stop_requested()) { paused_set = false; if (auto const next_time = Advance(); next_time) { // There are more events left in the queue, wait until the next event. - auto wait_time = *next_time - GetGlobalTimeNs().count(); + auto const wait_time = *next_time - GetGlobalTimeNs().count(); if (wait_time > 0) { -#ifdef _WIN32 - while (!paused && !event.IsSet() && wait_time > 0) { - wait_time = *next_time - GetGlobalTimeNs().count(); - if (wait_time >= timer_resolution_ns) { - Common::Windows::SleepForOneTick(); - } else { -#ifdef ARCHITECTURE_x86_64 - Common::X64::MicroSleep(); -#else - std::this_thread::yield(); -#endif - } - } - if (event.IsSet()) - event.Reset(); -#else event.WaitFor(std::chrono::nanoseconds(wait_time)); -#endif } } else { // Queue is empty, wait until another event is scheduled and signals us to @@ -226,7 +208,7 @@ void CoreTiming::ResetTicks() { } u64 CoreTiming::GetClockTicks() const { - u64 fres = is_multicore ? clock.GetCNTPCT() : Common::WallClock::CPUTickToCNTPCT(cpu_ticks); + u64 fres = is_multicore ? Common::g_wall_clock.GetCNTPCT() : Common::WallClock::CPUTickToCNTPCT(cpu_ticks); if (auto const overclock = Settings::values.fast_cpu_time.GetValue(); overclock != Settings::CpuClock::Off) { fres = u64(f64(fres) * (1.7 + 0.3 * u32(overclock))); } @@ -240,7 +222,7 @@ u64 CoreTiming::GetClockTicks() const { u64 CoreTiming::GetGPUTicks() const { return is_multicore - ? clock.GetGPUTick() + ? Common::g_wall_clock.GetGPUTick() : Common::WallClock::CPUTickToGPUTick(cpu_ticks); } @@ -317,14 +299,14 @@ void CoreTiming::Reset() { /// @brief Returns current time in nanoseconds. std::chrono::nanoseconds CoreTiming::GetGlobalTimeNs() const noexcept { return is_multicore - ? clock.GetTimeNS() + ? Common::g_wall_clock.GetTimeNS() : std::chrono::nanoseconds{Common::WallClock::CPUTickToNS(cpu_ticks)}; } /// @brief Returns current time in microseconds. std::chrono::microseconds CoreTiming::GetGlobalTimeUs() const noexcept { return is_multicore - ? clock.GetTimeUS() + ? Common::g_wall_clock.GetTimeUS() : std::chrono::microseconds{Common::WallClock::CPUTickToUS(cpu_ticks)}; } -- cgit v1.2.3