sys_lwmutex: add vm::temporary_unlock

This commit is contained in:
Nekotekina 2019-06-20 14:42:06 +03:00
parent b9b591bf02
commit a935203a18
3 changed files with 26 additions and 16 deletions

View File

@ -42,7 +42,7 @@ error_code sys_lwmutex_create(ppu_thread& ppu, vm::ptr<sys_lwmutex_t> lwmutex, v
attrs->flags = 0; attrs->flags = 0;
attrs->name_u64 = attr->name_u64; 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; return res;
} }
@ -76,7 +76,7 @@ error_code sys_lwmutex_destroy(ppu_thread& ppu, vm::ptr<sys_lwmutex_t> lwmutex)
} }
// call the syscall // 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 // unlock the mutex if failed
sys_lwmutex_unlock(ppu, lwmutex); sys_lwmutex_unlock(ppu, lwmutex);
@ -302,7 +302,7 @@ error_code sys_lwmutex_trylock(ppu_thread& ppu, vm::ptr<sys_lwmutex_t> lwmutex)
if (old_owner == lwmutex_reserved) if (old_owner == lwmutex_reserved)
{ {
// should be locked by the syscall // 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) if (res == CELL_OK)
{ {
@ -359,7 +359,7 @@ error_code sys_lwmutex_unlock(ppu_thread& ppu, vm::ptr<sys_lwmutex_t> lwmutex)
lwmutex->vars.owner.release(lwmutex_free); lwmutex->vars.owner.release(lwmutex_free);
// Call the alternative syscall // 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; return CELL_ESRCH;
} }

View File

@ -7,14 +7,14 @@
#include "Emu/Cell/PPUThread.h" #include "Emu/Cell/PPUThread.h"
#include "sys_lwmutex.h" #include "sys_lwmutex.h"
LOG_CHANNEL(sys_lwmutex); LOG_CHANNEL(sys_lwmutex);
extern u64 get_system_time(); extern u64 get_system_time();
error_code _sys_lwmutex_create(vm::ptr<u32> lwmutex_id, u32 protocol, vm::ptr<sys_lwmutex_t> control, s32 has_name, u64 name) error_code _sys_lwmutex_create(ppu_thread& ppu, vm::ptr<u32> lwmutex_id, u32 protocol, vm::ptr<sys_lwmutex_t> 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); 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) if (protocol != SYS_SYNC_FIFO && protocol != SYS_SYNC_RETRY && protocol != SYS_SYNC_PRIORITY)
@ -37,8 +37,10 @@ error_code _sys_lwmutex_create(vm::ptr<u32> lwmutex_id, u32 protocol, vm::ptr<sy
return CELL_EAGAIN; return CELL_EAGAIN;
} }
error_code _sys_lwmutex_destroy(u32 lwmutex_id) error_code _sys_lwmutex_destroy(ppu_thread& ppu, u32 lwmutex_id)
{ {
vm::temporary_unlock(ppu);
sys_lwmutex.warning("_sys_lwmutex_destroy(lwmutex_id=0x%x)", lwmutex_id); sys_lwmutex.warning("_sys_lwmutex_destroy(lwmutex_id=0x%x)", lwmutex_id);
const auto mutex = idm::withdraw<lv2_obj, lv2_lwmutex>(lwmutex_id, [&](lv2_lwmutex& mutex) -> CellError const auto mutex = idm::withdraw<lv2_obj, lv2_lwmutex>(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) 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); sys_lwmutex.trace("_sys_lwmutex_lock(lwmutex_id=0x%x, timeout=0x%llx)", lwmutex_id, timeout);
ppu.gpr[3] = CELL_OK; 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); std::lock_guard lock(mutex.mutex);
auto [old, _] = mutex.signaled.fetch_op([](s32& value) auto [old, _] = mutex.signaled.fetch_op([](s32& value)
{ {
if (value) if (value)
{ {
value = 0; 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]); 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); sys_lwmutex.trace("_sys_lwmutex_trylock(lwmutex_id=0x%x)", lwmutex_id);
const auto mutex = idm::check<lv2_obj, lv2_lwmutex>(lwmutex_id, [&](lv2_lwmutex& mutex) const auto mutex = idm::check<lv2_obj, lv2_lwmutex>(lwmutex_id, [&](lv2_lwmutex& mutex)
{ {
auto [_, ok] = mutex.signaled.fetch_op([](s32& value) auto [_, ok] = mutex.signaled.fetch_op([](s32& value)
{ {
if (value & 1) if (value & 1)
{ {
value = 0; 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) 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); sys_lwmutex.trace("_sys_lwmutex_unlock(lwmutex_id=0x%x)", lwmutex_id);
const auto mutex = idm::check<lv2_obj, lv2_lwmutex>(lwmutex_id, [&](lv2_lwmutex& mutex) -> cpu_thread* const auto mutex = idm::check<lv2_obj, lv2_lwmutex>(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; 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); sys_lwmutex.warning("_sys_lwmutex_unlock2(lwmutex_id=0x%x)", lwmutex_id);
const auto mutex = idm::check<lv2_obj, lv2_lwmutex>(lwmutex_id, [&](lv2_lwmutex& mutex) -> cpu_thread* const auto mutex = idm::check<lv2_obj, lv2_lwmutex>(lwmutex_id, [&](lv2_lwmutex& mutex) -> cpu_thread*

View File

@ -74,9 +74,9 @@ class ppu_thread;
// Syscalls // Syscalls
error_code _sys_lwmutex_create(vm::ptr<u32> lwmutex_id, u32 protocol, vm::ptr<sys_lwmutex_t> control, s32 has_name, u64 name); error_code _sys_lwmutex_create(ppu_thread& ppu, vm::ptr<u32> lwmutex_id, u32 protocol, vm::ptr<sys_lwmutex_t> control, s32 has_name, u64 name);
error_code _sys_lwmutex_destroy(u32 lwmutex_id); 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_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_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);