diff --git a/rpcs3/Emu/Cell/lv2/sys_cond.cpp b/rpcs3/Emu/Cell/lv2/sys_cond.cpp index 6e571d01b..98cce5afa 100644 --- a/rpcs3/Emu/Cell/lv2/sys_cond.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_cond.cpp @@ -318,6 +318,9 @@ error_code sys_cond_wait(ppu_thread& ppu, u32 cond_id, u64 timeout) return static_cast(syscall_state >> 32); } + // Register waiter + lv2_obj::emplace(cond.sq, &ppu); + // Unlock the mutex const u32 count = cond.mutex->lock_count.exchange(0); @@ -325,6 +328,7 @@ error_code sys_cond_wait(ppu_thread& ppu, u32 cond_id, u64 timeout) { if (cpu->state & cpu_flag::again) { + ensure(cond.unqueue(cond.sq, &ppu)); ppu.state += cpu_flag::again; return 0; } @@ -332,9 +336,6 @@ error_code sys_cond_wait(ppu_thread& ppu, u32 cond_id, u64 timeout) cond.mutex->append(cpu); } - // Register waiter - lv2_obj::emplace(cond.sq, &ppu); - // Sleep current thread and schedule mutex waiter cond.sleep(ppu, timeout); diff --git a/rpcs3/Emu/Cell/lv2/sys_lwmutex.h b/rpcs3/Emu/Cell/lv2/sys_lwmutex.h index 86552aa32..34a19d028 100644 --- a/rpcs3/Emu/Cell/lv2/sys_lwmutex.h +++ b/rpcs3/Emu/Cell/lv2/sys_lwmutex.h @@ -123,6 +123,11 @@ struct lv2_lwmutex final : lv2_obj lwcond_waiters.notify_all(); } + if (signal) + { + cpu->next_cpu = nullptr; + } + return signal; } @@ -158,8 +163,9 @@ struct lv2_lwmutex final : lv2_obj res = nullptr; } - if (auto sq = data.sq) + if (auto sq = static_cast(data.sq)) { + restore_next = sq->next_cpu; res = schedule(data.sq, protocol); if (sq == data.sq) @@ -167,7 +173,6 @@ struct lv2_lwmutex final : lv2_obj return false; } - restore_next = res->next_cpu; return true; } else diff --git a/rpcs3/Emu/Cell/lv2/sys_mutex.h b/rpcs3/Emu/Cell/lv2/sys_mutex.h index 4c668625c..2565dfe7e 100644 --- a/rpcs3/Emu/Cell/lv2/sys_mutex.h +++ b/rpcs3/Emu/Cell/lv2/sys_mutex.h @@ -101,7 +101,7 @@ struct lv2_mutex final : lv2_obj template bool try_own(T& cpu) { - return control.atomic_op([&](control_data_t& data) + if (control.atomic_op([&](control_data_t& data) { if (data.owner) { @@ -114,7 +114,13 @@ struct lv2_mutex final : lv2_obj data.owner = cpu.id; return true; } - }); + })) + { + cpu.next_cpu = nullptr; + return true; + } + + return false; } template @@ -161,8 +167,9 @@ struct lv2_mutex final : lv2_obj res = nullptr; } - if (auto sq = data.sq) + if (auto sq = static_cast(data.sq)) { + restore_next = sq->next_cpu; res = schedule(data.sq, protocol); if (sq == data.sq) @@ -171,7 +178,6 @@ struct lv2_mutex final : lv2_obj return false; } - restore_next = res->next_cpu; data.owner = res->id; return true; }