From d8664c8da4d1a9dc91f4cfe0aaeb60784ea36567 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Fri, 2 Jan 2015 19:02:31 +0300 Subject: [PATCH] Bugfix --- rpcs3/Emu/Cell/SPUThread.cpp | 2 +- rpcs3/Emu/SysCalls/lv2/sleep_queue_type.cpp | 4 ++++ rpcs3/Emu/SysCalls/lv2/sys_cond.cpp | 2 +- rpcs3/Emu/SysCalls/lv2/sys_event.cpp | 2 +- rpcs3/Emu/SysCalls/lv2/sys_lwmutex.cpp | 2 +- rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp | 2 +- rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp | 2 +- rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp | 8 ++++---- 8 files changed, 14 insertions(+), 10 deletions(-) diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index 53e8af2fab..3c3ec5d759 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -1118,7 +1118,7 @@ void SPUThread::StopAndSignal(u32 code) SPU.In_MBox.PushUncond((u32)event.data1); SPU.In_MBox.PushUncond((u32)event.data2); SPU.In_MBox.PushUncond((u32)event.data3); - if (!eq->sq.invalidate(tid, eq->protocol)) + if (!eq->sq.invalidate(tid, eq->protocol) && !eq->sq.pop(tid, eq->protocol)) { assert(!"sys_spu_thread_receive_event() failed (receiving)"); } diff --git a/rpcs3/Emu/SysCalls/lv2/sleep_queue_type.cpp b/rpcs3/Emu/SysCalls/lv2/sleep_queue_type.cpp index e9dbff141c..e2e7da4b6a 100644 --- a/rpcs3/Emu/SysCalls/lv2/sleep_queue_type.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sleep_queue_type.cpp @@ -210,6 +210,10 @@ bool sleep_queue_t::invalidate(u32 tid, u32 protocol) { if (v == tid) { + if (&v == m_signaled.data()) + { + return false; // if the thread is signaled, pop() should be used + } m_signaled.erase(m_signaled.begin() + (&v - m_signaled.data())); return true; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp b/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp index 580fbc2fa6..67c9e1001c 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp @@ -191,7 +191,7 @@ s32 sys_cond_wait(PPUThread& CPU, u32 cond_id, u64 timeout) } } - if (pushed_in_sleep_queue && !mutex->queue.invalidate(tid, mutex->protocol)) + if (pushed_in_sleep_queue && !mutex->queue.invalidate(tid, mutex->protocol) && !mutex->queue.pop(tid, mutex->protocol)) { assert(!"sys_cond_wait() failed (locking)"); } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_event.cpp b/rpcs3/Emu/SysCalls/lv2/sys_event.cpp index 3e833749fe..305fccdacb 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_event.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_event.cpp @@ -210,7 +210,7 @@ s32 sys_event_queue_receive(u32 equeue_id, vm::ptr dummy_event, t.GPR[5] = event.data1; t.GPR[6] = event.data2; t.GPR[7] = event.data3; - if (!eq->sq.invalidate(tid, eq->protocol)) + if (!eq->sq.invalidate(tid, eq->protocol) && !eq->sq.pop(tid, eq->protocol)) { assert(!"sys_event_queue_receive() failed (receiving)"); } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.cpp b/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.cpp index c1fea17291..0e5eae950c 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.cpp @@ -210,7 +210,7 @@ s32 sys_lwmutex_t::lock(be_t tid, u64 timeout) } } - if (!sq->invalidate(tid, attribute)) + if (!sq->invalidate(tid, attribute) && !sq->pop(tid, attribute)) { assert(!"sys_lwmutex_t::lock() failed (locking)"); } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp b/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp index 6f93b4b647..07ca016830 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp @@ -160,7 +160,7 @@ s32 sys_mutex_lock(PPUThread& CPU, u32 mutex_id, u64 timeout) } } - if (!mutex->queue.invalidate(tid, mutex->protocol)) + if (!mutex->queue.invalidate(tid, mutex->protocol) && !mutex->queue.pop(tid, mutex->protocol)) { assert(!"sys_mutex_lock() failed (locking)"); } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp b/rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp index d1b17416e4..7190e5dfc0 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp @@ -212,7 +212,7 @@ s32 sys_rwlock_wlock(PPUThread& CPU, u32 rw_lock_id, u64 timeout) } } - if (!rw->wqueue.invalidate(tid, rw->protocol)) + if (!rw->wqueue.invalidate(tid, rw->protocol) && !rw->wqueue.pop(tid, rw->protocol)) { assert(!"sys_rwlock_wlock() failed (locking)"); } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp b/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp index 21723ef2de..a5291cc684 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp @@ -100,8 +100,6 @@ s32 sys_semaphore_wait(u32 sem_id, u64 timeout) s32 old_value; { - LV2_LOCK(0); - sem->value.atomic_op_sync([&old_value](s32& value) { old_value = value; @@ -134,6 +132,10 @@ s32 sys_semaphore_wait(u32 sem_id, u64 timeout) { if (!sem->queue.invalidate(tid, sem->protocol)) { + if (sem->queue.pop(tid, sem->protocol)) + { + return CELL_OK; + } assert(!"sys_semaphore_wait() failed (timeout)"); } return CELL_ETIMEDOUT; @@ -195,8 +197,6 @@ s32 sys_semaphore_post(u32 sem_id, s32 count) return CELL_EINVAL; } - LV2_LOCK(0); - if (count + sem->value.read_sync() - (s32)sem->queue.count() > sem->max) { return CELL_EBUSY;