2012-11-15 00:39:56 +01:00
|
|
|
#include "stdafx.h"
|
|
|
|
|
#include "Emu/SysCalls/SysCalls.h"
|
2014-01-19 22:19:37 +01:00
|
|
|
#include "Emu/SysCalls/lv2/SC_Lwmutex.h"
|
|
|
|
|
#include <mutex>
|
2012-11-15 00:39:56 +01:00
|
|
|
|
2014-01-19 22:19:37 +01:00
|
|
|
SysCallBase sc_lwmutex("sys_lwmutex");
|
2012-11-15 00:39:56 +01:00
|
|
|
|
2014-01-19 22:19:37 +01:00
|
|
|
int sys_lwmutex_create(mem_ptr_t<sys_lwmutex_t> lwmutex, mem_ptr_t<sys_lwmutex_attribute_t> attr)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-02-09 12:11:48 +01:00
|
|
|
sc_lwmutex.Log("sys_lwmutex_create(lwmutex_addr=0x%x, lwmutex_attr_addr=0x%x)",
|
2014-01-19 22:19:37 +01:00
|
|
|
lwmutex.GetAddr(), attr.GetAddr());
|
2012-11-15 00:39:56 +01:00
|
|
|
|
2014-01-19 22:19:37 +01:00
|
|
|
if (!lwmutex.IsGood() || !attr.IsGood()) return CELL_EFAULT;
|
2012-11-15 00:39:56 +01:00
|
|
|
|
2014-02-06 23:55:48 +01:00
|
|
|
switch (attr->attr_recursive.ToBE())
|
2013-07-06 01:49:38 +02:00
|
|
|
{
|
2014-02-06 23:55:48 +01:00
|
|
|
case se32(SYS_SYNC_RECURSIVE): break;
|
|
|
|
|
case se32(SYS_SYNC_NOT_RECURSIVE): break;
|
2014-02-09 12:11:48 +01:00
|
|
|
default: sc_lwmutex.Error("Unknown 0x%x recursive attr", (u32)attr->attr_recursive); return CELL_EINVAL;
|
2013-07-06 01:49:38 +02:00
|
|
|
}
|
|
|
|
|
|
2014-02-06 23:55:48 +01:00
|
|
|
switch (attr->attr_protocol.ToBE())
|
2014-01-19 22:19:37 +01:00
|
|
|
{
|
2014-02-09 12:11:48 +01:00
|
|
|
case se32(SYS_SYNC_PRIORITY): break;
|
2014-02-06 23:55:48 +01:00
|
|
|
case se32(SYS_SYNC_RETRY): break;
|
2014-02-09 12:11:48 +01:00
|
|
|
case se32(SYS_SYNC_PRIORITY_INHERIT): sc_lwmutex.Error("Invalid SYS_SYNC_PRIORITY_INHERIT protocol attr"); return CELL_EINVAL;
|
|
|
|
|
case se32(SYS_SYNC_FIFO): break;
|
|
|
|
|
default: sc_lwmutex.Error("Unknown 0x%x protocol attr", (u32)attr->attr_protocol); return CELL_EINVAL;
|
2014-01-19 22:19:37 +01:00
|
|
|
}
|
|
|
|
|
|
2014-02-09 12:11:48 +01:00
|
|
|
lwmutex->attribute = attr->attr_protocol | attr->attr_recursive;
|
2014-01-19 22:19:37 +01:00
|
|
|
lwmutex->all_info = 0;
|
|
|
|
|
lwmutex->pad = 0;
|
|
|
|
|
lwmutex->recursive_count = 0;
|
|
|
|
|
|
2014-02-09 12:11:48 +01:00
|
|
|
u32 sq_id = sc_lwmutex.GetNewId(new SleepQueue(attr->name_u64));
|
|
|
|
|
lwmutex->sleep_queue = sq_id;
|
|
|
|
|
|
|
|
|
|
sc_lwmutex.Log("*** lwmutex created [%s] (attribute=0x%x): sleep_queue=0x%x",
|
|
|
|
|
attr->name, (u32)lwmutex->attribute, sq_id);
|
2012-11-15 00:39:56 +01:00
|
|
|
|
2013-06-30 10:46:29 +02:00
|
|
|
return CELL_OK;
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
|
|
|
|
|
2014-01-19 22:19:37 +01:00
|
|
|
int sys_lwmutex_destroy(mem_ptr_t<sys_lwmutex_t> lwmutex)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-02-09 12:11:48 +01:00
|
|
|
sc_lwmutex.Log("sys_lwmutex_destroy(lwmutex_addr=0x%x)", lwmutex.GetAddr());
|
2014-01-29 21:31:09 +01:00
|
|
|
|
|
|
|
|
if (!lwmutex.IsGood()) return CELL_EFAULT;
|
|
|
|
|
|
2014-02-09 12:11:48 +01:00
|
|
|
u32 sq_id = lwmutex->sleep_queue;
|
|
|
|
|
if (!Emu.GetIdManager().CheckID(sq_id)) return CELL_ESRCH;
|
|
|
|
|
|
2014-02-05 12:55:32 +01:00
|
|
|
// try to make it unable to lock
|
2014-02-06 23:55:48 +01:00
|
|
|
switch (int res = lwmutex->trylock(~0))
|
|
|
|
|
{
|
2014-02-09 12:11:48 +01:00
|
|
|
case CELL_OK:
|
|
|
|
|
lwmutex->attribute = 0;
|
|
|
|
|
lwmutex->sleep_queue = 0;
|
|
|
|
|
Emu.GetIdManager().RemoveID(sq_id);
|
|
|
|
|
default: return res;
|
2014-02-06 23:55:48 +01:00
|
|
|
}
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
|
|
|
|
|
2014-01-19 22:19:37 +01:00
|
|
|
int sys_lwmutex_lock(mem_ptr_t<sys_lwmutex_t> lwmutex, u64 timeout)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-02-01 11:17:15 +01:00
|
|
|
sc_lwmutex.Log("sys_lwmutex_lock(lwmutex_addr=0x%x, timeout=%lld)", lwmutex.GetAddr(), timeout);
|
2014-01-19 22:19:37 +01:00
|
|
|
|
|
|
|
|
if (!lwmutex.IsGood()) return CELL_EFAULT;
|
2013-06-30 10:46:29 +02:00
|
|
|
|
2014-02-05 12:55:32 +01:00
|
|
|
return lwmutex->lock(GetCurrentPPUThread().GetId(), timeout ? ((timeout < 1000) ? 1 : (timeout / 1000)) : 0);
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
|
|
|
|
|
2014-01-19 22:19:37 +01:00
|
|
|
int sys_lwmutex_trylock(mem_ptr_t<sys_lwmutex_t> lwmutex)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-02-01 11:17:15 +01:00
|
|
|
sc_lwmutex.Log("sys_lwmutex_trylock(lwmutex_addr=0x%x)", lwmutex.GetAddr());
|
2013-06-30 10:46:29 +02:00
|
|
|
|
2014-01-19 22:19:37 +01:00
|
|
|
if (!lwmutex.IsGood()) return CELL_EFAULT;
|
|
|
|
|
|
2014-01-31 00:40:05 +01:00
|
|
|
return lwmutex->trylock(GetCurrentPPUThread().GetId());
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
|
|
|
|
|
2014-01-19 22:19:37 +01:00
|
|
|
int sys_lwmutex_unlock(mem_ptr_t<sys_lwmutex_t> lwmutex)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-02-01 11:17:15 +01:00
|
|
|
sc_lwmutex.Log("sys_lwmutex_unlock(lwmutex_addr=0x%x)", lwmutex.GetAddr());
|
2014-01-19 22:19:37 +01:00
|
|
|
|
|
|
|
|
if (!lwmutex.IsGood()) return CELL_EFAULT;
|
2013-06-30 10:46:29 +02:00
|
|
|
|
2014-02-06 23:55:48 +01:00
|
|
|
return lwmutex->unlock(GetCurrentPPUThread().GetId());
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
2013-06-30 10:46:29 +02:00
|
|
|
|