diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index 625080a3ac..21701389e3 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -3506,16 +3506,30 @@ static bool ppu_store_reservation(ppu_thread& ppu, u32 addr, u64 reg_value) if (ppu.res_notify_time == (vm::reservation_acquire(notify) & -128)) { + ppu.state += cpu_flag::wait; vm::reservation_notifier(notify).notify_all(); notified = true; } - if (!notified || (addr ^ notify) & -128) + if (get_resrv_waiters_count(addr)) { - res.notify_all(); + if (!notified) + { + ppu.res_notify = addr; + ppu.res_notify_time = rtime + 128; + } + else if ((addr ^ notify) & -128) + { + res.notify_all(); + ppu.res_notify = 0; + } + } + else + { + ppu.res_notify = 0; } - ppu.res_notify = 0; + static_cast(ppu.test_stopped()); } else { @@ -3546,7 +3560,9 @@ static bool ppu_store_reservation(ppu_thread& ppu, u32 addr, u64 reg_value) { if (ppu.res_notify_time == (vm::reservation_acquire(notify) & -128)) { + ppu.state += cpu_flag::wait; vm::reservation_notifier(notify).notify_all(); + static_cast(ppu.test_stopped()); } ppu.res_notify = 0; diff --git a/rpcs3/Emu/Cell/lv2/sys_cond.cpp b/rpcs3/Emu/Cell/lv2/sys_cond.cpp index e6a5e16c34..765948a908 100644 --- a/rpcs3/Emu/Cell/lv2/sys_cond.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_cond.cpp @@ -538,6 +538,8 @@ error_code sys_cond_wait(ppu_thread& ppu, u32 cond_id, u64 timeout) continue; } + ppu.state += cpu_flag::wait; + std::lock_guard lock(cond->mutex->mutex); // Try to cancel the waiting diff --git a/rpcs3/Emu/Cell/lv2/sys_event.cpp b/rpcs3/Emu/Cell/lv2/sys_event.cpp index c6a5b94c07..3047f87fa6 100644 --- a/rpcs3/Emu/Cell/lv2/sys_event.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_event.cpp @@ -521,6 +521,8 @@ error_code sys_event_queue_receive(ppu_thread& ppu, u32 equeue_id, vm::ptr::load(queue->pq)) { // Waiters queue is empty, so the thread must have been signaled diff --git a/rpcs3/Emu/Cell/lv2/sys_event_flag.cpp b/rpcs3/Emu/Cell/lv2/sys_event_flag.cpp index c32e08246d..7da6563517 100644 --- a/rpcs3/Emu/Cell/lv2/sys_event_flag.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_event_flag.cpp @@ -240,6 +240,8 @@ error_code sys_event_flag_wait(ppu_thread& ppu, u32 id, u64 bitptn, u32 mode, vm continue; } + ppu.state += cpu_flag::wait; + if (!atomic_storage::load(flag->sq)) { // Waiters queue is empty, so the thread must have been signaled diff --git a/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp b/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp index 501f5ac37b..6ffd9b29e6 100644 --- a/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp @@ -572,6 +572,8 @@ error_code _sys_lwcond_queue_wait(ppu_thread& ppu, u32 lwcond_id, u32 lwmutex_id continue; } + ppu.state += cpu_flag::wait; + std::lock_guard lock(cond->mutex); if (cond->unqueue(cond->sq, &ppu)) diff --git a/rpcs3/Emu/Cell/lv2/sys_lwmutex.cpp b/rpcs3/Emu/Cell/lv2/sys_lwmutex.cpp index aebb12f37d..20a210cbcb 100644 --- a/rpcs3/Emu/Cell/lv2/sys_lwmutex.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_lwmutex.cpp @@ -234,6 +234,8 @@ error_code _sys_lwmutex_lock(ppu_thread& ppu, u32 lwmutex_id, u64 timeout) continue; } + ppu.state += cpu_flag::wait; + if (!mutex->load_sq()) { // Sleep queue is empty, so the thread must have been signaled diff --git a/rpcs3/Emu/Cell/lv2/sys_mutex.cpp b/rpcs3/Emu/Cell/lv2/sys_mutex.cpp index b1c7a4c5ed..efd0f1c374 100644 --- a/rpcs3/Emu/Cell/lv2/sys_mutex.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_mutex.cpp @@ -255,6 +255,8 @@ error_code sys_mutex_lock(ppu_thread& ppu, u32 mutex_id, u64 timeout) continue; } + ppu.state += cpu_flag::wait; + if (!atomic_storage::load(mutex->control.raw().sq)) { // Waiters queue is empty, so the thread must have been signaled diff --git a/rpcs3/Emu/Cell/lv2/sys_rwlock.cpp b/rpcs3/Emu/Cell/lv2/sys_rwlock.cpp index 5009a87752..fe77f6b421 100644 --- a/rpcs3/Emu/Cell/lv2/sys_rwlock.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_rwlock.cpp @@ -196,6 +196,8 @@ error_code sys_rwlock_rlock(ppu_thread& ppu, u32 rw_lock_id, u64 timeout) continue; } + ppu.state += cpu_flag::wait; + if (!atomic_storage::load(rwlock->rq)) { // Waiters queue is empty, so the thread must have been signaled diff --git a/rpcs3/Emu/Cell/lv2/sys_semaphore.cpp b/rpcs3/Emu/Cell/lv2/sys_semaphore.cpp index 68a27ab881..7cf7ffd03d 100644 --- a/rpcs3/Emu/Cell/lv2/sys_semaphore.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_semaphore.cpp @@ -202,6 +202,8 @@ error_code sys_semaphore_wait(ppu_thread& ppu, u32 sem_id, u64 timeout) continue; } + ppu.state += cpu_flag::wait; + std::lock_guard lock(sem->mutex); if (!sem->unqueue(sem->sq, &ppu))