From a935203a18a2e2a29a89c727b83e734ae507a0db Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Thu, 20 Jun 2019 14:42:06 +0300 Subject: [PATCH] sys_lwmutex: add vm::temporary_unlock --- rpcs3/Emu/Cell/Modules/sys_lwmutex_.cpp | 8 ++++---- rpcs3/Emu/Cell/lv2/sys_lwmutex.cpp | 26 +++++++++++++++++-------- rpcs3/Emu/Cell/lv2/sys_lwmutex.h | 8 ++++---- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/sys_lwmutex_.cpp b/rpcs3/Emu/Cell/Modules/sys_lwmutex_.cpp index 29789a2a95..e8feda368c 100644 --- a/rpcs3/Emu/Cell/Modules/sys_lwmutex_.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_lwmutex_.cpp @@ -42,7 +42,7 @@ error_code sys_lwmutex_create(ppu_thread& ppu, vm::ptr lwmutex, v attrs->flags = 0; attrs->name_u64 = attr->name_u64; - if (error_code res = g_cfg.core.hle_lwmutex ? sys_mutex_create(ppu, out_id, attrs) : _sys_lwmutex_create(out_id, protocol, lwmutex, 0x80000001, attr->name_u64)) + if (error_code res = g_cfg.core.hle_lwmutex ? sys_mutex_create(ppu, out_id, attrs) : _sys_lwmutex_create(ppu, out_id, protocol, lwmutex, 0x80000001, attr->name_u64)) { return res; } @@ -76,7 +76,7 @@ error_code sys_lwmutex_destroy(ppu_thread& ppu, vm::ptr lwmutex) } // call the syscall - if (error_code res = _sys_lwmutex_destroy(lwmutex->sleep_queue)) + if (error_code res = _sys_lwmutex_destroy(ppu, lwmutex->sleep_queue)) { // unlock the mutex if failed sys_lwmutex_unlock(ppu, lwmutex); @@ -302,7 +302,7 @@ error_code sys_lwmutex_trylock(ppu_thread& ppu, vm::ptr lwmutex) if (old_owner == lwmutex_reserved) { // should be locked by the syscall - const error_code res = _sys_lwmutex_trylock(lwmutex->sleep_queue); + const error_code res = _sys_lwmutex_trylock(ppu, lwmutex->sleep_queue); if (res == CELL_OK) { @@ -359,7 +359,7 @@ error_code sys_lwmutex_unlock(ppu_thread& ppu, vm::ptr lwmutex) lwmutex->vars.owner.release(lwmutex_free); // Call the alternative syscall - if (_sys_lwmutex_unlock2(lwmutex->sleep_queue) == CELL_ESRCH) + if (_sys_lwmutex_unlock2(ppu, lwmutex->sleep_queue) == CELL_ESRCH) { return CELL_ESRCH; } diff --git a/rpcs3/Emu/Cell/lv2/sys_lwmutex.cpp b/rpcs3/Emu/Cell/lv2/sys_lwmutex.cpp index d48a7427f3..ad39578037 100644 --- a/rpcs3/Emu/Cell/lv2/sys_lwmutex.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_lwmutex.cpp @@ -7,14 +7,14 @@ #include "Emu/Cell/PPUThread.h" #include "sys_lwmutex.h" - - LOG_CHANNEL(sys_lwmutex); extern u64 get_system_time(); -error_code _sys_lwmutex_create(vm::ptr lwmutex_id, u32 protocol, vm::ptr control, s32 has_name, u64 name) +error_code _sys_lwmutex_create(ppu_thread& ppu, vm::ptr lwmutex_id, u32 protocol, vm::ptr control, s32 has_name, u64 name) { + vm::temporary_unlock(ppu); + sys_lwmutex.warning("_sys_lwmutex_create(lwmutex_id=*0x%x, protocol=0x%x, control=*0x%x, has_name=0x%x, name=0x%llx)", lwmutex_id, protocol, control, has_name, name); if (protocol != SYS_SYNC_FIFO && protocol != SYS_SYNC_RETRY && protocol != SYS_SYNC_PRIORITY) @@ -37,8 +37,10 @@ error_code _sys_lwmutex_create(vm::ptr lwmutex_id, u32 protocol, vm::ptr(lwmutex_id, [&](lv2_lwmutex& mutex) -> CellError @@ -68,6 +70,8 @@ error_code _sys_lwmutex_destroy(u32 lwmutex_id) error_code _sys_lwmutex_lock(ppu_thread& ppu, u32 lwmutex_id, u64 timeout) { + vm::temporary_unlock(ppu); + sys_lwmutex.trace("_sys_lwmutex_lock(lwmutex_id=0x%x, timeout=0x%llx)", lwmutex_id, timeout); ppu.gpr[3] = CELL_OK; @@ -82,7 +86,7 @@ error_code _sys_lwmutex_lock(ppu_thread& ppu, u32 lwmutex_id, u64 timeout) std::lock_guard lock(mutex.mutex); auto [old, _] = mutex.signaled.fetch_op([](s32& value) - { + { if (value) { value = 0; @@ -153,14 +157,16 @@ error_code _sys_lwmutex_lock(ppu_thread& ppu, u32 lwmutex_id, u64 timeout) return not_an_error(ppu.gpr[3]); } -error_code _sys_lwmutex_trylock(u32 lwmutex_id) +error_code _sys_lwmutex_trylock(ppu_thread& ppu, u32 lwmutex_id) { + vm::temporary_unlock(ppu); + sys_lwmutex.trace("_sys_lwmutex_trylock(lwmutex_id=0x%x)", lwmutex_id); const auto mutex = idm::check(lwmutex_id, [&](lv2_lwmutex& mutex) { auto [_, ok] = mutex.signaled.fetch_op([](s32& value) - { + { if (value & 1) { value = 0; @@ -188,6 +194,8 @@ error_code _sys_lwmutex_trylock(u32 lwmutex_id) error_code _sys_lwmutex_unlock(ppu_thread& ppu, u32 lwmutex_id) { + vm::temporary_unlock(ppu); + sys_lwmutex.trace("_sys_lwmutex_unlock(lwmutex_id=0x%x)", lwmutex_id); const auto mutex = idm::check(lwmutex_id, [&](lv2_lwmutex& mutex) -> cpu_thread* @@ -216,8 +224,10 @@ error_code _sys_lwmutex_unlock(ppu_thread& ppu, u32 lwmutex_id) return CELL_OK; } -error_code _sys_lwmutex_unlock2(u32 lwmutex_id) +error_code _sys_lwmutex_unlock2(ppu_thread& ppu, u32 lwmutex_id) { + vm::temporary_unlock(ppu); + sys_lwmutex.warning("_sys_lwmutex_unlock2(lwmutex_id=0x%x)", lwmutex_id); const auto mutex = idm::check(lwmutex_id, [&](lv2_lwmutex& mutex) -> cpu_thread* diff --git a/rpcs3/Emu/Cell/lv2/sys_lwmutex.h b/rpcs3/Emu/Cell/lv2/sys_lwmutex.h index 30e3ea6d01..5ee8a6c8bf 100644 --- a/rpcs3/Emu/Cell/lv2/sys_lwmutex.h +++ b/rpcs3/Emu/Cell/lv2/sys_lwmutex.h @@ -74,9 +74,9 @@ class ppu_thread; // Syscalls -error_code _sys_lwmutex_create(vm::ptr lwmutex_id, u32 protocol, vm::ptr control, s32 has_name, u64 name); -error_code _sys_lwmutex_destroy(u32 lwmutex_id); +error_code _sys_lwmutex_create(ppu_thread& ppu, vm::ptr lwmutex_id, u32 protocol, vm::ptr control, s32 has_name, u64 name); +error_code _sys_lwmutex_destroy(ppu_thread& ppu, u32 lwmutex_id); error_code _sys_lwmutex_lock(ppu_thread& ppu, u32 lwmutex_id, u64 timeout); -error_code _sys_lwmutex_trylock(u32 lwmutex_id); +error_code _sys_lwmutex_trylock(ppu_thread& ppu, u32 lwmutex_id); error_code _sys_lwmutex_unlock(ppu_thread& ppu, u32 lwmutex_id); -error_code _sys_lwmutex_unlock2(u32 lwmutex_id); +error_code _sys_lwmutex_unlock2(ppu_thread& ppu, u32 lwmutex_id);