diff --git a/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp b/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp index 1178466114..bde908e6d8 100644 --- a/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp @@ -16,13 +16,24 @@ error_code _sys_lwcond_create(ppu_thread& ppu, vm::ptr lwcond_id, u32 lwmut sys_lwcond.warning("_sys_lwcond_create(lwcond_id=*0x%x, lwmutex_id=0x%x, control=*0x%x, name=0x%llx, arg5=0x%x)", lwcond_id, lwmutex_id, control, name, arg5); - // Temporarily - if (!idm::check(lwmutex_id)) + u32 protocol; + + // Extract protocol from lwmutex + if (!idm::check(lwmutex_id, [&protocol](lv2_lwmutex& mutex) + { + protocol = mutex.protocol; + })) { return CELL_ESRCH; } - if (const u32 id = idm::make(name, lwmutex_id, control)) + if (protocol == SYS_SYNC_RETRY) + { + // Lwcond can't have SYS_SYNC_RETRY protocol + protocol = SYS_SYNC_PRIORITY; + } + + if (const u32 id = idm::make(name, lwmutex_id, protocol, control)) { *lwcond_id = id; return CELL_OK; @@ -114,7 +125,7 @@ error_code _sys_lwcond_signal(ppu_thread& ppu, u32 lwcond_id, u32 lwmutex_id, u3 } else { - result = cond.schedule(cond.sq, cond.control->lwmutex->attribute & SYS_SYNC_ATTR_PROTOCOL_MASK); + result = cond.schedule(cond.sq, cond.protocol); } if (result) @@ -206,7 +217,7 @@ error_code _sys_lwcond_signal_all(ppu_thread& ppu, u32 lwcond_id, u32 lwmutex_id u32 result = 0; - while (const auto cpu = cond.schedule(cond.sq, cond.control->lwmutex->attribute & SYS_SYNC_ATTR_PROTOCOL_MASK)) + while (const auto cpu = cond.schedule(cond.sq, cond.protocol)) { cond.waiters--; diff --git a/rpcs3/Emu/Cell/lv2/sys_lwcond.h b/rpcs3/Emu/Cell/lv2/sys_lwcond.h index ce38c4feec..6e9c353977 100644 --- a/rpcs3/Emu/Cell/lv2/sys_lwcond.h +++ b/rpcs3/Emu/Cell/lv2/sys_lwcond.h @@ -27,15 +27,17 @@ struct lv2_lwcond final : lv2_obj const u64 name; const u32 lwid; + const u32 protocol; vm::ptr control; shared_mutex mutex; atomic_t waiters{0}; std::deque sq; - lv2_lwcond(u64 name, u32 lwid, vm::ptr control) + lv2_lwcond(u64 name, u32 lwid, u32 protocol, vm::ptr control) : name(name) , lwid(lwid) + , protocol(protocol) , control(control) { }