2012-11-15 00:39:56 +01:00
|
|
|
#include "stdafx.h"
|
|
|
|
|
#include "Emu/SysCalls/SysCalls.h"
|
|
|
|
|
|
|
|
|
|
struct lwmutex_lock_info
|
|
|
|
|
{
|
|
|
|
|
u32 owner;
|
|
|
|
|
u32 waiter;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
union lwmutex_variable
|
|
|
|
|
{
|
|
|
|
|
lwmutex_lock_info info;
|
|
|
|
|
u64 all_info;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct lwmutex
|
|
|
|
|
{
|
|
|
|
|
lwmutex_variable lock_var;
|
|
|
|
|
u32 attribute;
|
|
|
|
|
u32 recursive_count;
|
|
|
|
|
u32 sleep_queue;
|
|
|
|
|
u32 pad;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct lwmutex_attr
|
|
|
|
|
{
|
|
|
|
|
u32 attr_protocol;
|
|
|
|
|
u32 attr_recursive;
|
|
|
|
|
char name[8];
|
|
|
|
|
};
|
|
|
|
|
|
2013-06-30 10:46:29 +02:00
|
|
|
SysCallBase sc_lwmutex("sys_wmutex");
|
2012-11-15 00:39:56 +01:00
|
|
|
|
2013-06-30 10:46:29 +02:00
|
|
|
int sys_lwmutex_create(u64 lwmutex_addr, u64 lwmutex_attr_addr)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2013-07-06 01:49:38 +02:00
|
|
|
if(!Memory.IsGoodAddr(lwmutex_addr, 4) || !Memory.IsGoodAddr(lwmutex_attr_addr))
|
|
|
|
|
{
|
|
|
|
|
return CELL_EFAULT;
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-30 10:46:29 +02:00
|
|
|
lwmutex& lmtx = (lwmutex&)Memory[lwmutex_addr];
|
2013-07-06 01:49:38 +02:00
|
|
|
lmtx.lock_var.all_info = 0;
|
2013-06-30 10:46:29 +02:00
|
|
|
lwmutex_attr& lmtx_attr = (lwmutex_attr&)Memory[lwmutex_attr_addr];
|
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
|
|
|
}
|
|
|
|
|
|
2013-06-30 10:46:29 +02:00
|
|
|
int sys_lwmutex_destroy(u64 lwmutex_addr)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2013-06-30 10:46:29 +02:00
|
|
|
//sc_lwmutex.Warning("sys_lwmutex_destroy(lwmutex_addr = 0x%llx)", lwmutex_addr);
|
2012-11-15 00:39:56 +01:00
|
|
|
|
2013-07-06 01:49:38 +02:00
|
|
|
//lwmutex& lmtx = (lwmutex&)Memory[lwmutex_addr];
|
|
|
|
|
//Emu.GetIdManager().RemoveID(lmtx.attribute);
|
2013-06-30 10:46:29 +02:00
|
|
|
|
|
|
|
|
return CELL_OK;
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
|
|
|
|
|
2013-06-30 10:46:29 +02:00
|
|
|
int sys_lwmutex_lock(u64 lwmutex_addr, u64 timeout)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2013-06-30 10:46:29 +02:00
|
|
|
lwmutex& lmtx = (lwmutex&)Memory[lwmutex_addr];
|
|
|
|
|
|
2013-07-06 01:49:38 +02:00
|
|
|
PPCThread& thr = GetCurrentPPUThread();
|
|
|
|
|
|
|
|
|
|
if(thr.GetId() == re(lmtx.lock_var.info.owner))
|
|
|
|
|
{
|
|
|
|
|
re(lmtx.recursive_count, re(lmtx.recursive_count) + 1);
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-30 10:46:29 +02:00
|
|
|
if(!lmtx.lock_var.info.owner)
|
|
|
|
|
{
|
|
|
|
|
re(lmtx.lock_var.info.owner, GetCurrentPPUThread().GetId());
|
2013-07-06 01:49:38 +02:00
|
|
|
re(lmtx.recursive_count, 1);
|
2013-06-30 10:46:29 +02:00
|
|
|
}
|
|
|
|
|
else if(!lmtx.lock_var.info.waiter)
|
|
|
|
|
{
|
2013-07-06 01:49:38 +02:00
|
|
|
thr.Wait(true);
|
|
|
|
|
re(lmtx.lock_var.info.waiter, thr.GetId());
|
2013-06-30 10:46:29 +02:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2013-07-06 01:49:38 +02:00
|
|
|
ConLog.Warning("lwmutex has waiter!");
|
|
|
|
|
return CELL_EBUSY;
|
2013-06-30 10:46:29 +02:00
|
|
|
}
|
2013-07-06 01:49:38 +02:00
|
|
|
|
2013-06-30 10:46:29 +02:00
|
|
|
return CELL_OK;
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
|
|
|
|
|
2013-06-30 10:46:29 +02:00
|
|
|
int sys_lwmutex_trylock(u64 lwmutex_addr)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2013-06-30 10:46:29 +02:00
|
|
|
//sc_lwmutex.Warning("sys_lwmutex_trylock(lwmutex_addr = 0x%llx)", lwmutex_addr);
|
|
|
|
|
lwmutex& lmtx = (lwmutex&)Memory[lwmutex_addr];
|
|
|
|
|
|
|
|
|
|
if(lmtx.lock_var.info.owner) return CELL_EBUSY;
|
|
|
|
|
|
|
|
|
|
return CELL_OK;
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
|
|
|
|
|
2013-06-30 10:46:29 +02:00
|
|
|
int sys_lwmutex_unlock(u64 lwmutex_addr)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2013-06-30 10:46:29 +02:00
|
|
|
//sc_lwmutex.Warning("sys_lwmutex_unlock(lwmutex_addr = 0x%llx)", lwmutex_addr);
|
|
|
|
|
|
|
|
|
|
lwmutex& lmtx = (lwmutex&)Memory[lwmutex_addr];
|
2013-07-06 01:49:38 +02:00
|
|
|
|
|
|
|
|
re(lmtx.recursive_count, re(lmtx.recursive_count) - 1);
|
|
|
|
|
|
|
|
|
|
if(!lmtx.recursive_count)
|
|
|
|
|
{
|
|
|
|
|
if(lmtx.lock_var.info.owner = lmtx.lock_var.info.waiter)
|
|
|
|
|
{
|
|
|
|
|
lmtx.lock_var.info.waiter = 0;
|
2013-11-03 20:23:16 +01:00
|
|
|
CPUThread* thr = Emu.GetCPU().GetThread(lmtx.lock_var.info.owner);
|
2013-07-06 01:49:38 +02:00
|
|
|
if(thr)
|
|
|
|
|
{
|
|
|
|
|
thr->Wait(false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-06-30 10:46:29 +02:00
|
|
|
|
|
|
|
|
return CELL_OK;
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
2013-06-30 10:46:29 +02:00
|
|
|
|