From 5d13978bbf22f5ebf92e678a169423f1e713e7df Mon Sep 17 00:00:00 2001 From: Eladash Date: Wed, 26 Apr 2023 08:50:22 +0300 Subject: [PATCH] sys_lwcond: Implement TIMEOUT on lwmutex lock --- rpcs3/Emu/Cell/lv2/sys_lwcond.cpp | 39 ++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp b/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp index a50683413b..4bab5ba2d6 100644 --- a/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp @@ -461,28 +461,41 @@ error_code _sys_lwcond_queue_wait(ppu_thread& ppu, u32 lwcond_id, u32 lwmutex_id break; } - reader_lock lock2(mutex->mutex); + std::lock_guard lock2(mutex->mutex); - bool mutex_sleep = false; + bool success = false; - for (auto cpu = mutex->load_sq(); cpu; cpu = cpu->next_cpu) + mutex->lv2_control.fetch_op([&](lv2_lwmutex::control_data_t& data) { - if (cpu == &ppu) + success = false; + + ppu_thread* sq = static_cast(data.sq); + + const bool retval = &ppu == sq; + + if (!mutex->unqueue(sq, &ppu)) { - mutex_sleep = true; - break; + return false; } - } - if (!mutex_sleep) + success = true; + + if (!retval) + { + return false; + } + + data.sq = sq; + return true; + }); + + if (success) { - break; + ppu.next_cpu = nullptr; + ppu.gpr[3] = CELL_ETIMEDOUT; } - mutex->sleep(ppu); - ppu.start_time = start_time; // Restore start time because awake has been called - timeout = 0; - continue; + break; } } else