From 49be6be8f4886e7dfc86f22e17d6adb8de98d906 Mon Sep 17 00:00:00 2001 From: Eladash Date: Sat, 29 Apr 2023 08:12:59 +0300 Subject: [PATCH] LV2/Timer: Make timers consistent --- rpcs3/Emu/Cell/lv2/sys_timer.cpp | 13 +++++++------ rpcs3/Emu/Cell/lv2/sys_timer.h | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/rpcs3/Emu/Cell/lv2/sys_timer.cpp b/rpcs3/Emu/Cell/lv2/sys_timer.cpp index 6364b4ce2d..8128964545 100644 --- a/rpcs3/Emu/Cell/lv2/sys_timer.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_timer.cpp @@ -48,15 +48,14 @@ void lv2_timer::save(utils::serial& ar) ar(state), lv2_event_queue::save_ptr(ar, port.get()), ar(source, data1, data2, expire, period); } -u64 lv2_timer::check() noexcept +u64 lv2_timer::check(u64 _now) noexcept { - while (thread_ctrl::state() != thread_state::aborting) + while (true) { const u32 _state = +state; if (_state == SYS_TIMER_STATE_RUN) { - const u64 _now = get_guest_system_time(); u64 next = expire; // If aborting, perform the last accurate check for event @@ -83,7 +82,7 @@ u64 lv2_timer::check_unlocked(u64 _now) noexcept if (_now < next || state != SYS_TIMER_STATE_RUN) { - return; + return umax; } if (port) @@ -95,7 +94,7 @@ u64 lv2_timer::check_unlocked(u64 _now) noexcept { // Set next expiration time and check again const u64 expire0 = utils::add_saturate(next, period); - expire.release(_expire0); + expire.release(expire0); return expire0 - _now; } @@ -134,13 +133,15 @@ void lv2_timer_thread::operator()() continue; } + const u64 _now = get_guest_system_time(); + reader_lock lock(mutex); for (const auto& timer : timers) { if (lv2_obj::check(timer)) { - const u64 advised_sleep_time = timer->check(); + const u64 advised_sleep_time = timer->check(_now); if (sleep_time > advised_sleep_time) { diff --git a/rpcs3/Emu/Cell/lv2/sys_timer.h b/rpcs3/Emu/Cell/lv2/sys_timer.h index 7845531986..b88bc5c390 100644 --- a/rpcs3/Emu/Cell/lv2/sys_timer.h +++ b/rpcs3/Emu/Cell/lv2/sys_timer.h @@ -36,7 +36,7 @@ struct lv2_timer : lv2_obj atomic_t expire{0}; // Next expiration time atomic_t period{0}; // Period (oneshot if 0) - u64 check() noexcept; + u64 check(u64 _now) noexcept; u64 check_unlocked(u64 _now) noexcept; lv2_timer() noexcept