2013-06-30 10:46:29 +02:00
|
|
|
#include "stdafx.h"
|
|
|
|
|
#include "Emu/SysCalls/SysCalls.h"
|
|
|
|
|
#include "SC_Mutex.h"
|
|
|
|
|
|
|
|
|
|
SysCallBase sys_cond("sys_cond");
|
|
|
|
|
extern SysCallBase sys_mtx;
|
|
|
|
|
|
|
|
|
|
struct condition_attr
|
|
|
|
|
{
|
|
|
|
|
u32 pshared;
|
|
|
|
|
int flags;
|
|
|
|
|
u64 ipc_key;
|
|
|
|
|
char name[8];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct condition
|
|
|
|
|
{
|
|
|
|
|
wxCondition cond;
|
|
|
|
|
condition_attr attr;
|
|
|
|
|
|
|
|
|
|
condition(wxMutex& mtx, const condition_attr& attr)
|
|
|
|
|
: cond(mtx)
|
|
|
|
|
, attr(attr)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
int sys_cond_create(u32 cond_addr, u32 mutex_id, u32 attr_addr)
|
|
|
|
|
{
|
2014-02-03 14:12:25 +01:00
|
|
|
sys_cond.Warning("sys_cond_create(cond_addr=0x%x, mutex_id=0x%x, attr_addr=%d)",
|
2013-06-30 10:46:29 +02:00
|
|
|
cond_addr, mutex_id, attr_addr);
|
|
|
|
|
|
|
|
|
|
if(!Memory.IsGoodAddr(cond_addr) || !Memory.IsGoodAddr(attr_addr)) return CELL_EFAULT;
|
|
|
|
|
|
|
|
|
|
condition_attr attr = (condition_attr&)Memory[attr_addr];
|
|
|
|
|
|
|
|
|
|
attr.pshared = re(attr.pshared);
|
|
|
|
|
attr.ipc_key = re(attr.ipc_key);
|
|
|
|
|
attr.flags = re(attr.flags);
|
|
|
|
|
|
|
|
|
|
sys_cond.Log("*** pshared = %d", attr.pshared);
|
|
|
|
|
sys_cond.Log("*** ipc_key = 0x%llx", attr.ipc_key);
|
|
|
|
|
sys_cond.Log("*** flags = 0x%x", attr.flags);
|
|
|
|
|
sys_cond.Log("*** name = %s", attr.name);
|
|
|
|
|
|
|
|
|
|
mutex* mtx_data = nullptr;
|
|
|
|
|
if(!sys_mtx.CheckId(mutex_id, mtx_data)) return CELL_ESRCH;
|
|
|
|
|
|
|
|
|
|
Memory.Write32(cond_addr, sys_cond.GetNewId(new condition(mtx_data->mtx, attr)));
|
|
|
|
|
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int sys_cond_destroy(u32 cond_id)
|
|
|
|
|
{
|
|
|
|
|
sys_cond.Log("sys_cond_destroy(cond_id=0x%x)", cond_id);
|
|
|
|
|
|
|
|
|
|
if(!sys_cond.CheckId(cond_id)) return CELL_ESRCH;
|
|
|
|
|
|
|
|
|
|
Emu.GetIdManager().RemoveID(cond_id);
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int sys_cond_wait(u32 cond_id, u64 timeout)
|
|
|
|
|
{
|
|
|
|
|
sys_cond.Log("sys_cond_wait(cond_id=0x%x, timeout=0x%llx)", cond_id, timeout);
|
|
|
|
|
|
|
|
|
|
condition* cond_data = nullptr;
|
|
|
|
|
if(!sys_cond.CheckId(cond_id, cond_data)) return CELL_ESRCH;
|
|
|
|
|
|
2014-02-03 14:12:25 +01:00
|
|
|
u32 counter = 0;
|
|
|
|
|
const u32 max_counter = timeout ? (timeout / 1000) : 20000;
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
if (Emu.IsStopped()) return CELL_ETIMEDOUT;
|
|
|
|
|
|
|
|
|
|
switch (cond_data->cond.WaitTimeout(1))
|
|
|
|
|
{
|
2014-02-03 21:23:05 +01:00
|
|
|
case wxCOND_NO_ERROR: return CELL_OK;
|
|
|
|
|
case wxCOND_TIMEOUT: break;
|
2014-02-03 14:12:25 +01:00
|
|
|
default: return CELL_EPERM;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (counter++ > max_counter)
|
|
|
|
|
{
|
|
|
|
|
if (!timeout)
|
|
|
|
|
{
|
|
|
|
|
sys_cond.Warning("sys_cond_wait(cond_id=0x%x, timeout=0x%llx): TIMEOUT", cond_id, timeout);
|
|
|
|
|
counter = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return CELL_ETIMEDOUT;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} while (true);
|
2013-06-30 10:46:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int sys_cond_signal(u32 cond_id)
|
|
|
|
|
{
|
|
|
|
|
sys_cond.Log("sys_cond_signal(cond_id=0x%x)", cond_id);
|
|
|
|
|
|
|
|
|
|
condition* cond_data = nullptr;
|
|
|
|
|
if(!sys_cond.CheckId(cond_id, cond_data)) return CELL_ESRCH;
|
|
|
|
|
|
|
|
|
|
cond_data->cond.Signal();
|
|
|
|
|
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int sys_cond_signal_all(u32 cond_id)
|
|
|
|
|
{
|
|
|
|
|
sys_cond.Log("sys_cond_signal_all(cond_id=0x%x)", cond_id);
|
|
|
|
|
|
|
|
|
|
condition* cond_data = nullptr;
|
|
|
|
|
if(!sys_cond.CheckId(cond_id, cond_data)) return CELL_ESRCH;
|
|
|
|
|
|
|
|
|
|
cond_data->cond.Broadcast();
|
|
|
|
|
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
}
|