diff --git a/rpcs3/Emu/CPU/CPUThread.cpp b/rpcs3/Emu/CPU/CPUThread.cpp index 41ecbdee0e..1c814f6a65 100644 --- a/rpcs3/Emu/CPU/CPUThread.cpp +++ b/rpcs3/Emu/CPU/CPUThread.cpp @@ -337,17 +337,13 @@ namespace cpu_counter return; } - // Unregister and wait if necessary - verify(HERE), _this->state & cpu_flag::wait; - if (slot >= std::size(s_cpu_list)) { sys_log.fatal("Index out of bounds (%u)." HERE, slot); return; } - std::lock_guard lock(s_cpu_lock); - + // Asynchronous unregister if (!s_cpu_list[slot].compare_and_swap_test(_this, nullptr)) { sys_log.fatal("Inconsistency for array slot %u", slot); @@ -519,6 +515,8 @@ void cpu_thread::operator()() cpu_counter::remove(_this); } + s_cpu_lock.lock_unlock(); + s_cpu_counter--; g_tls_current_cpu_thread = nullptr; @@ -592,7 +590,7 @@ bool cpu_thread::check_state() noexcept { bool store = false; - if (flags & cpu_flag::pause) + if (flags & cpu_flag::pause && s_tls_thread_slot != umax) { // Save value before state is saved and cpu_flag::wait is observed if (s_tls_sctr == umax) @@ -614,6 +612,13 @@ bool cpu_thread::check_state() noexcept } else { + // Cleanup after asynchronous remove() + if (flags & cpu_flag::pause && s_tls_thread_slot == umax) + { + flags -= cpu_flag::pause; + store = true; + } + s_tls_sctr = -1; }