diff --git a/rpcs3/Emu/CPU/CPUThread.cpp b/rpcs3/Emu/CPU/CPUThread.cpp index 27607781af..139f918373 100644 --- a/rpcs3/Emu/CPU/CPUThread.cpp +++ b/rpcs3/Emu/CPU/CPUThread.cpp @@ -588,7 +588,7 @@ void cpu_thread::operator()() continue; } - thread_ctrl::wait_on(state, state0); + state.wait(state0); if (state & cpu_flag::ret && state.test_and_reset(cpu_flag::ret)) { @@ -640,7 +640,7 @@ cpu_thread::cpu_thread(u32 id) void cpu_thread::cpu_wait(bs_t old) { - thread_ctrl::wait_on(state, old); + state.wait(old); } static atomic_t s_dummy_atomic = 0; diff --git a/rpcs3/Emu/Cell/Modules/cellMsgDialog.cpp b/rpcs3/Emu/Cell/Modules/cellMsgDialog.cpp index a06f4fc75d..cd69853c08 100644 --- a/rpcs3/Emu/Cell/Modules/cellMsgDialog.cpp +++ b/rpcs3/Emu/Cell/Modules/cellMsgDialog.cpp @@ -245,7 +245,7 @@ error_code open_msg_dialog(bool is_blocking, u32 type, vm::cptr msgString, break; } - thread_ctrl::wait_on(ppu.state, state); + ppu.state.wait(state); } if (is_blocking) diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index 59d769390b..9de26568af 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -1641,7 +1641,10 @@ void spu_thread::cleanup() vm::free_range_lock(range_lock); // Signal the debugger about the termination - state += cpu_flag::exit; + if (!state.test_and_set(cpu_flag::exit)) + { + state.notify_one(); + } } spu_thread::~spu_thread() diff --git a/rpcs3/Emu/Cell/lv2/lv2.cpp b/rpcs3/Emu/Cell/lv2/lv2.cpp index f8a88dabea..e28f621241 100644 --- a/rpcs3/Emu/Cell/lv2/lv2.cpp +++ b/rpcs3/Emu/Cell/lv2/lv2.cpp @@ -1605,9 +1605,13 @@ void lv2_obj::schedule_all(u64 current_time) if (target->state & cpu_flag::suspend) { ppu_log.trace("schedule(): %s", target->id); - target->state.atomic_op(FN(x += cpu_flag::signal, x -= cpu_flag::suspend)); target->start_time = 0; + if ((target->state.fetch_op(FN(x += cpu_flag::signal, x -= cpu_flag::suspend, void())) & (cpu_flag::wait + cpu_flag::signal)) != cpu_flag::wait) + { + continue; + } + if (notify_later_idx == std::size(g_to_notify)) { // Out of notification slots, notify locally (resizable container is not worth it) diff --git a/rpcs3/Emu/Cell/lv2/sys_cond.cpp b/rpcs3/Emu/Cell/lv2/sys_cond.cpp index 8db28a9328..b6b6bb2e75 100644 --- a/rpcs3/Emu/Cell/lv2/sys_cond.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_cond.cpp @@ -452,7 +452,7 @@ error_code sys_cond_wait(ppu_thread& ppu, u32 cond_id, u64 timeout) } else { - thread_ctrl::wait_on(ppu.state, state); + ppu.state.wait(state); } } diff --git a/rpcs3/Emu/Cell/lv2/sys_event.cpp b/rpcs3/Emu/Cell/lv2/sys_event.cpp index e5ee920a97..cd83840f81 100644 --- a/rpcs3/Emu/Cell/lv2/sys_event.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_event.cpp @@ -524,7 +524,7 @@ error_code sys_event_queue_receive(ppu_thread& ppu, u32 equeue_id, vm::ptr break; } - thread_ctrl::wait_on(ppu.state, state); + ppu.state.wait(state); } if (ppu.gpr[3] == static_cast(-SYS_NET_EINTR)) @@ -579,7 +579,7 @@ error_code sys_net_bnet_connect(ppu_thread& ppu, s32 s, vm::ptr(-SYS_NET_EINTR)) @@ -859,7 +859,7 @@ error_code sys_net_bnet_recvfrom(ppu_thread& ppu, s32 s, vm::ptr buf, u32 break; } - thread_ctrl::wait_on(ppu.state, state); + ppu.state.wait(state); } if (ppu.gpr[3] == static_cast(-SYS_NET_EINTR)) @@ -1053,7 +1053,7 @@ error_code sys_net_bnet_sendto(ppu_thread& ppu, s32 s, vm::cptr buf, u32 l { break; } - thread_ctrl::wait_on(ppu.state, state); + ppu.state.wait(state); } if (ppu.gpr[3] == static_cast(-SYS_NET_EINTR)) @@ -1408,7 +1408,7 @@ error_code sys_net_bnet_poll(ppu_thread& ppu, vm::ptr fds, s32 n } else { - thread_ctrl::wait_on(ppu.state, state); + ppu.state.wait(state); } } @@ -1648,7 +1648,7 @@ error_code sys_net_bnet_select(ppu_thread& ppu, s32 nfds, vm::ptr ar break; } - thread_ctrl::wait_on(ppu.state, state); + ppu.state.wait(state); } } diff --git a/rpcs3/Emu/Cell/lv2/sys_rwlock.cpp b/rpcs3/Emu/Cell/lv2/sys_rwlock.cpp index 7147ac1388..3a75aea91e 100644 --- a/rpcs3/Emu/Cell/lv2/sys_rwlock.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_rwlock.cpp @@ -209,7 +209,7 @@ error_code sys_rwlock_rlock(ppu_thread& ppu, u32 rw_lock_id, u64 timeout) } else { - thread_ctrl::wait_on(ppu.state, state); + ppu.state.wait(state); } } @@ -472,7 +472,7 @@ error_code sys_rwlock_wlock(ppu_thread& ppu, u32 rw_lock_id, u64 timeout) } else { - thread_ctrl::wait_on(ppu.state, state); + ppu.state.wait(state); } } diff --git a/rpcs3/Emu/Cell/lv2/sys_semaphore.cpp b/rpcs3/Emu/Cell/lv2/sys_semaphore.cpp index 72e35b2156..ece3dcae52 100644 --- a/rpcs3/Emu/Cell/lv2/sys_semaphore.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_semaphore.cpp @@ -213,7 +213,7 @@ error_code sys_semaphore_wait(ppu_thread& ppu, u32 sem_id, u64 timeout) } else { - thread_ctrl::wait_on(ppu.state, state); + ppu.state.wait(state); } } diff --git a/rpcs3/Emu/Cell/lv2/sys_spu.cpp b/rpcs3/Emu/Cell/lv2/sys_spu.cpp index d2652bf924..4d242c3073 100644 --- a/rpcs3/Emu/Cell/lv2/sys_spu.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_spu.cpp @@ -1493,7 +1493,7 @@ error_code sys_spu_thread_group_join(ppu_thread& ppu, u32 id, vm::ptr cause break; } - thread_ctrl::wait_on(ppu.state, state); + ppu.state.wait(state); } } while (false); diff --git a/rpcs3/Emu/Cell/lv2/sys_usbd.cpp b/rpcs3/Emu/Cell/lv2/sys_usbd.cpp index 7b68e755b8..76c0759fd1 100644 --- a/rpcs3/Emu/Cell/lv2/sys_usbd.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_usbd.cpp @@ -891,7 +891,7 @@ error_code sys_usbd_receive_event(ppu_thread& ppu, u32 handle, vm::ptr arg1 break; } - thread_ctrl::wait_on(ppu.state, state); + ppu.state.wait(state); } ppu.check_state();