diff --git a/rpcs3/Emu/CPU/CPUThread.cpp b/rpcs3/Emu/CPU/CPUThread.cpp index a32619da4c..037619ec06 100644 --- a/rpcs3/Emu/CPU/CPUThread.cpp +++ b/rpcs3/Emu/CPU/CPUThread.cpp @@ -531,6 +531,7 @@ bool cpu_thread::check_state() noexcept } bool cpu_sleep_called = false; + bool cpu_can_stop = true; bool escape, retval; u64 susp_ctr = -1; @@ -551,6 +552,14 @@ bool cpu_thread::check_state() noexcept susp_ctr = -1; } + if (flags & cpu_flag::temp) + { + // Sticky flag, indicates check_state() is not allowed to return true + flags -= cpu_flag::temp; + cpu_can_stop = false; + store = true; + } + if (flags & cpu_flag::signal) { flags -= cpu_flag::signal; @@ -580,7 +589,7 @@ bool cpu_thread::check_state() noexcept store = true; } - retval = false; + retval = !cpu_can_stop; } else { @@ -593,8 +602,9 @@ bool cpu_thread::check_state() noexcept retval = true; } - if (flags & cpu_flag::dbg_step) + if (cpu_can_stop && flags & cpu_flag::dbg_step) { + // Can't process dbg_step if we only paused temporarily flags += cpu_flag::dbg_pause; flags -= cpu_flag::dbg_step; store = true; diff --git a/rpcs3/Emu/CPU/CPUThread.h b/rpcs3/Emu/CPU/CPUThread.h index 11f62203fb..873c970714 100644 --- a/rpcs3/Emu/CPU/CPUThread.h +++ b/rpcs3/Emu/CPU/CPUThread.h @@ -11,6 +11,7 @@ enum class cpu_flag : u32 stop, // Thread not running (HLE, initial state) exit, // Irreversible exit wait, // Indicates waiting state, set by the thread itself + temp, // Indicates that the thread cannot properly return after next check_state() pause, // Thread suspended by suspend_all technique suspend, // Thread suspended ret, // Callback return requested diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index a4b3f66125..82fa302635 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -1219,7 +1219,7 @@ static T ppu_load_acquire_reservation(ppu_thread& ppu, u32 addr) } else { - ppu.state += cpu_flag::wait; + ppu.state += cpu_flag::wait + cpu_flag::temp; std::this_thread::yield(); ppu.check_state(); } diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index 7711c2c128..304e3c4d97 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -242,7 +242,7 @@ namespace spu if (atomic_instruction_table[pc_offset].load(std::memory_order_consume) >= max_concurrent_instructions) { - spu.state += cpu_flag::wait; + spu.state += cpu_flag::wait + cpu_flag::temp; if (timeout_ms > 0) { @@ -271,10 +271,7 @@ namespace spu busy_wait(count); } - if (spu.test_stopped()) - { - spu_runtime::g_escape(&spu); - } + spu.check_state(); } atomic_instruction_table[pc_offset]++; @@ -2516,13 +2513,14 @@ bool spu_thread::process_mfc_cmd() { if (g_use_rtm) { - state += cpu_flag::wait; + state += cpu_flag::wait + cpu_flag::temp; } std::this_thread::yield(); - if (test_stopped()) + if (g_use_rtm) { + verify(HERE), !check_state(); } } }()) @@ -2888,7 +2886,7 @@ s64 spu_thread::get_ch_value(u32 ch) { if (channel.get_count() == 0) { - state += cpu_flag::wait; + state += cpu_flag::wait + cpu_flag::temp; } for (int i = 0; i < 10 && channel.get_count() == 0; i++)