diff --git a/rpcs3/Emu/CPU/CPUThread.cpp b/rpcs3/Emu/CPU/CPUThread.cpp index 97376f3e23..b7f3f16f02 100644 --- a/rpcs3/Emu/CPU/CPUThread.cpp +++ b/rpcs3/Emu/CPU/CPUThread.cpp @@ -578,10 +578,11 @@ bool cpu_thread::check_state() noexcept susp_ctr = -1; } - if (flags & cpu_flag::temp) + if (flags & cpu_flag::temp) [[unlikely]] { // Sticky flag, indicates check_state() is not allowed to return true flags -= cpu_flag::temp; + flags -= cpu_flag::wait; cpu_can_stop = false; store = true; } @@ -619,7 +620,7 @@ bool cpu_thread::check_state() noexcept } else { - if (!(flags & cpu_flag::wait)) + if (cpu_can_stop && !(flags & cpu_flag::wait)) { flags += cpu_flag::wait; store = true; @@ -649,6 +650,8 @@ bool cpu_thread::check_state() noexcept s_tls_thread_slot = g_fxo->get()->add(this, true); } + verify(HERE), cpu_can_stop || !retval; + verify(HERE), cpu_can_stop || !(state & cpu_flag::wait); return retval; } @@ -657,7 +660,7 @@ bool cpu_thread::check_state() noexcept cpu_sleep(); cpu_sleep_called = true; - if (s_tls_thread_slot != umax) + if (cpu_can_stop && s_tls_thread_slot != umax) { // Exclude inactive threads from the suspend list (optimization) std::lock_guard lock(g_fxo->get()->cpu_suspend_lock); diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index 7a9ed9e56c..9844471289 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -1219,9 +1219,9 @@ static T ppu_load_acquire_reservation(ppu_thread& ppu, u32 addr) } else { - ppu.state += cpu_flag::wait + cpu_flag::temp; + ppu.state += cpu_flag::wait; std::this_thread::yield(); - verify(HERE), !ppu.check_state(); + ppu.check_state(); } }()) { diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index 823fa8cdea..35d702a860 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -2651,17 +2651,9 @@ bool spu_thread::process_mfc_cmd() } else { - if (g_use_rtm) - { - state += cpu_flag::wait + cpu_flag::temp; - } - + state += cpu_flag::wait + cpu_flag::temp; std::this_thread::yield(); - - if (g_use_rtm) - { - verify(HERE), !check_state(); - } + !check_state(); } }()) { diff --git a/rpcs3/Emu/Memory/vm.cpp b/rpcs3/Emu/Memory/vm.cpp index b6ea17f655..6ea1f9323a 100644 --- a/rpcs3/Emu/Memory/vm.cpp +++ b/rpcs3/Emu/Memory/vm.cpp @@ -261,13 +261,15 @@ namespace vm void passive_lock(cpu_thread& cpu) { + bool ok = true; + if (!g_tls_locked || *g_tls_locked != &cpu) [[unlikely]] { _register_lock(&cpu); - if (cpu.state) [[likely]] + if (cpu.state & cpu_flag::memory) [[likely]] { - cpu.state -= cpu_flag::wait + cpu_flag::memory; + cpu.state -= cpu_flag::memory; } if (g_mutex.is_lockable()) @@ -275,22 +277,20 @@ namespace vm return; } - cpu.state += cpu_flag::wait; + ok = false; } - if (cpu.state & cpu_flag::wait) + if (!ok || cpu.state & cpu_flag::memory) { while (true) { g_mutex.lock_unlock(); - cpu.state -= cpu_flag::wait + cpu_flag::memory; + cpu.state -= cpu_flag::memory; if (g_mutex.is_lockable()) [[likely]] { return; } - - cpu.state += cpu_flag::wait; } } } @@ -345,7 +345,7 @@ namespace vm if (cpu) { - if (!g_tls_locked || *g_tls_locked != cpu) + if (!g_tls_locked || *g_tls_locked != cpu || cpu->state & cpu_flag::wait) { cpu = nullptr; } @@ -392,7 +392,7 @@ namespace vm if (cpu) { - if (!g_tls_locked || *g_tls_locked != cpu) + if (!g_tls_locked || *g_tls_locked != cpu || cpu->state & cpu_flag::wait) { cpu = nullptr; }