aboutsummaryrefslogtreecommitdiff
path: root/src/core/core_timing.cpp
diff options
context:
space:
mode:
authorlizzie <lizzie@eden-emu.dev>2026-05-15 22:06:38 +0200
committercrueter <crueter@eden-emu.dev>2026-05-15 22:06:38 +0200
commit975aa4e2f2128b865ec5738c2704c8d37af6a7b9 (patch)
treefeec00d92e12a8c8644ea1b18769d9b225a75c73 /src/core/core_timing.cpp
parenta1f9e68f46c729a49eeaec1a81d9ac26145d2509 (diff)
[common] remove ptr indirection on WallClock (#3864)
also devirtualizes manually since compiler doesn't do it with LTO Signed-off-by: lizzie <lizzie@eden-emu.dev> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3864 Reviewed-by: crueter <crueter@eden-emu.dev>
Diffstat (limited to 'src/core/core_timing.cpp')
-rw-r--r--src/core/core_timing.cpp155
1 files changed, 67 insertions, 88 deletions
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp
index b216dc2094..6738a0d73d 100644
--- a/src/core/core_timing.cpp
+++ b/src/core/core_timing.cpp
@@ -57,15 +57,51 @@ void CoreTiming::Initialize(std::function<void()>&& on_thread_init_) {
Reset();
on_thread_init = std::move(on_thread_init_);
event_fifo_id = 0;
- shutting_down = false;
cpu_ticks = 0;
if (is_multicore) {
- timer_thread.emplace([](CoreTiming& instance) {
+ timer_thread = std::jthread([this](std::stop_token stop_token) {
Common::SetCurrentThreadName("HostTiming");
Common::SetCurrentThreadPriority(Common::ThreadPriority::High);
- instance.on_thread_init();
- instance.ThreadLoop();
- }, std::ref(*this));
+ on_thread_init();
+ has_started = true;
+ 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();
+ 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
+ // continue.
+ wait_set = true;
+ event.Wait();
+ }
+ wait_set = false;
+ }
+ paused_set = true;
+ pause_event.Wait();
+ }
+ });
}
}
@@ -90,7 +126,7 @@ void CoreTiming::SyncPause(bool is_paused) {
}
Pause(is_paused);
- if (timer_thread) {
+ if (timer_thread.joinable()) {
if (!is_paused) {
pause_event.Set();
}
@@ -190,33 +226,22 @@ void CoreTiming::ResetTicks() {
}
u64 CoreTiming::GetClockTicks() const {
- u64 fres;
- if (is_multicore) [[likely]] {
- fres = clock->GetCNTPCT();
- } else {
- fres = Common::WallClock::CPUTickToCNTPCT(cpu_ticks);
+ u64 fres = is_multicore ? 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)));
}
-
- const auto overclock = Settings::values.fast_cpu_time.GetValue();
-
- if (overclock != Settings::CpuClock::Off) {
- fres = (u64) ((double) fres * (1.7 + 0.3 * u32(overclock)));
- }
-
- if (Settings::values.sync_core_speed.GetValue()) {
- const auto ticks = double(fres);
- const auto speed_limit = double(Settings::SpeedLimit())*0.01;
- return u64(ticks/speed_limit);
- } else {
- return fres;
- }
+ if (::Settings::values.sync_core_speed.GetValue()) {
+ auto const ticks = f64(fres);
+ auto const speed_limit = f64(Settings::SpeedLimit()) * 0.01;
+ return u64(ticks / speed_limit);
+ }
+ return fres;
}
u64 CoreTiming::GetGPUTicks() const {
- if (is_multicore) [[likely]] {
- return clock->GetGPUTick();
- }
- return Common::WallClock::CPUTickToGPUTick(cpu_ticks);
+ return is_multicore
+ ? clock.GetGPUTick()
+ : Common::WallClock::CPUTickToGPUTick(cpu_ticks);
}
std::optional<s64> CoreTiming::Advance() {
@@ -278,75 +303,29 @@ std::optional<s64> CoreTiming::Advance() {
}
}
-void CoreTiming::ThreadLoop() {
- has_started = true;
- while (!shutting_down) {
- while (!paused) {
- paused_set = false;
- const auto next_time = Advance();
- if (next_time) {
- // There are more events left in the queue, wait until the next event.
- auto 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
- // continue.
- wait_set = true;
- event.Wait();
- }
- wait_set = false;
- }
-
- paused_set = true;
- pause_event.Wait();
- }
-}
-
void CoreTiming::Reset() {
paused = true;
- shutting_down = true;
pause_event.Set();
event.Set();
- if (timer_thread) {
- timer_thread->join();
+ if (timer_thread.joinable()) {
+ timer_thread.request_stop();
+ timer_thread.join();
}
- timer_thread.reset();
has_started = false;
}
-std::chrono::nanoseconds CoreTiming::GetGlobalTimeNs() const {
- if (is_multicore) [[likely]] {
- return clock->GetTimeNS();
- }
- return std::chrono::nanoseconds{Common::WallClock::CPUTickToNS(cpu_ticks)};
+/// @brief Returns current time in nanoseconds.
+std::chrono::nanoseconds CoreTiming::GetGlobalTimeNs() const noexcept {
+ return is_multicore
+ ? clock.GetTimeNS()
+ : std::chrono::nanoseconds{Common::WallClock::CPUTickToNS(cpu_ticks)};
}
-std::chrono::microseconds CoreTiming::GetGlobalTimeUs() const {
- if (is_multicore) [[likely]] {
- return clock->GetTimeUS();
- }
- return std::chrono::microseconds{Common::WallClock::CPUTickToUS(cpu_ticks)};
+/// @brief Returns current time in microseconds.
+std::chrono::microseconds CoreTiming::GetGlobalTimeUs() const noexcept {
+ return is_multicore
+ ? clock.GetTimeUS()
+ : std::chrono::microseconds{Common::WallClock::CPUTickToUS(cpu_ticks)};
}
#ifdef _WIN32