mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-24 11:43:05 +01:00
Event flag partial implementation
This commit is contained in:
parent
4aa6ddf3dd
commit
1a1bed2258
@ -4,10 +4,10 @@
|
||||
enum
|
||||
{
|
||||
MFC_PUT_CMD = 0x20, MFC_PUTB_CMD = 0x21, MFC_PUTF_CMD = 0x22,
|
||||
MFC_PUTR_CMD = 0x30, MFC_PUTRB_CMD = 0x31, MFC_PUTRF_CMD = 0x32,
|
||||
MFC_PUTR_CMD = 0x30, MFC_PUTRB_CMD = 0x31, MFC_PUTRF_CMD = 0x32,
|
||||
MFC_GET_CMD = 0x40, MFC_GETB_CMD = 0x41, MFC_GETF_CMD = 0x42,
|
||||
MFC_PUTL_CMD = 0x24, MFC_PUTLB_CMD = 0x25, MFC_PUTLF_CMD = 0x26,
|
||||
MFC_PUTRL_CMD = 0x34, MFC_PUTRLB_CMD = 0x35, MFC_PUTRLF_CMD = 0x36,
|
||||
MFC_PUTRL_CMD = 0x34, MFC_PUTRLB_CMD = 0x35, MFC_PUTRLF_CMD = 0x36,
|
||||
MFC_GETL_CMD = 0x44, MFC_GETLB_CMD = 0x45, MFC_GETLF_CMD = 0x46,
|
||||
MFC_GETLLAR_CMD = 0xD0,
|
||||
MFC_PUTLLC_CMD = 0xB4,
|
||||
|
@ -113,14 +113,26 @@ private:
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x102: default:
|
||||
if (!CPU.SPU.Out_MBox.GetCount()) // the real exit status
|
||||
case 0x102:
|
||||
if (!CPU.SPU.Out_MBox.GetCount())
|
||||
{
|
||||
ConLog.Warning("STOP: 0x%x (no message)", code);
|
||||
ConLog.Error("sys_spu_thread_exit (no status, code 0x102)");
|
||||
}
|
||||
else if (Ini.HLELogging.GetValue() || code != 0x102)
|
||||
else if (Ini.HLELogging.GetValue())
|
||||
{
|
||||
ConLog.Warning("STOP: 0x%x (message=0x%x)", code, CPU.SPU.Out_MBox.GetValue());
|
||||
// the real exit status
|
||||
ConLog.Write("sys_spu_thread_exit (status=0x%x)", CPU.SPU.Out_MBox.GetValue());
|
||||
}
|
||||
CPU.Stop();
|
||||
break;
|
||||
default:
|
||||
if (!CPU.SPU.Out_MBox.GetCount())
|
||||
{
|
||||
ConLog.Error("Unknown STOP code: 0x%x (no message)", code);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConLog.Error("Unknown STOP code: 0x%x (message=0x%x)", code, CPU.SPU.Out_MBox.GetValue());
|
||||
}
|
||||
CPU.Stop();
|
||||
break;
|
||||
|
@ -6,7 +6,7 @@ SysCallBase sys_event_flag("sys_event_flag");
|
||||
|
||||
int sys_event_flag_create(mem32_t eflag_id, mem_ptr_t<sys_event_flag_attr> attr, u64 init)
|
||||
{
|
||||
sys_event_flag.Warning("sys_event_flag_create(eflag_id_addr=0x%x, attr_addr=0x%x, init=0x%llx)",
|
||||
sys_event_flag.Log("sys_event_flag_create(eflag_id_addr=0x%x, attr_addr=0x%x, init=0x%llx)",
|
||||
eflag_id.GetAddr(), attr.GetAddr(), init);
|
||||
|
||||
if(!eflag_id.IsGood() || !attr.IsGood())
|
||||
@ -30,8 +30,8 @@ int sys_event_flag_create(mem32_t eflag_id, mem_ptr_t<sys_event_flag_attr> attr,
|
||||
|
||||
switch (attr->type.ToBE())
|
||||
{
|
||||
case se32(SYS_SYNC_WAITER_SINGLE): sys_event_flag.Warning("TODO: SYS_SYNC_WAITER_SINGLE type"); break;
|
||||
case se32(SYS_SYNC_WAITER_MULTIPLE): sys_event_flag.Warning("TODO: SYS_SYNC_WAITER_MULTIPLE type"); break;
|
||||
case se32(SYS_SYNC_WAITER_SINGLE): break;
|
||||
case se32(SYS_SYNC_WAITER_MULTIPLE): sys_event_flag.Error("TODO: SYS_SYNC_WAITER_MULTIPLE type"); break;
|
||||
default: return CELL_EINVAL;
|
||||
}
|
||||
|
||||
@ -57,16 +57,136 @@ int sys_event_flag_destroy(u32 eflag_id)
|
||||
|
||||
int sys_event_flag_wait(u32 eflag_id, u64 bitptn, u32 mode, mem64_t result, u64 timeout)
|
||||
{
|
||||
sys_event_flag.Error("sys_event_flag_wait(eflag_id=%d, bitptn=0x%llx, mode=0x%x, result_addr=0x%x, timeout=%lld)",
|
||||
sys_event_flag.Warning("sys_event_flag_wait(eflag_id=%d, bitptn=0x%llx, mode=0x%x, result_addr=0x%x, timeout=%lld)",
|
||||
eflag_id, bitptn, mode, result.GetAddr(), timeout);
|
||||
return CELL_OK;
|
||||
|
||||
if (result.IsGood()) result = 0;
|
||||
|
||||
switch (mode & 0xf)
|
||||
{
|
||||
case SYS_EVENT_FLAG_WAIT_AND: break;
|
||||
case SYS_EVENT_FLAG_WAIT_OR: break;
|
||||
default: return CELL_EINVAL;
|
||||
}
|
||||
|
||||
switch (mode & ~0xf)
|
||||
{
|
||||
case 0: break; // ???
|
||||
case SYS_EVENT_FLAG_WAIT_CLEAR: break;
|
||||
case SYS_EVENT_FLAG_WAIT_CLEAR_ALL: break;
|
||||
default: return CELL_EINVAL;
|
||||
}
|
||||
|
||||
event_flag* ef;
|
||||
if(!sys_event_flag.CheckId(eflag_id, ef)) return CELL_ESRCH;
|
||||
|
||||
u32 tid = GetCurrentPPUThread().GetId();
|
||||
|
||||
ef->waiters.push(tid);
|
||||
if (ef->m_type == SYS_SYNC_WAITER_SINGLE && ef->waiters.list.GetCount() > 1)
|
||||
{
|
||||
ef->waiters.invalidate(tid);
|
||||
return CELL_EPERM;
|
||||
}
|
||||
|
||||
u32 counter = 0;
|
||||
const u32 max_counter = timeout ? (timeout / 1000) : ~0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
{
|
||||
SMutexLocker lock(ef->m_mutex);
|
||||
|
||||
u64 flags = ef->flags;
|
||||
|
||||
if (((mode & SYS_EVENT_FLAG_WAIT_AND) && (flags & bitptn) == bitptn) ||
|
||||
((mode & SYS_EVENT_FLAG_WAIT_OR) && (flags & bitptn)))
|
||||
{
|
||||
ef->waiters.invalidate(tid);
|
||||
|
||||
if (mode & SYS_EVENT_FLAG_WAIT_CLEAR)
|
||||
{
|
||||
ef->flags &= ~bitptn;
|
||||
}
|
||||
else if (mode & SYS_EVENT_FLAG_WAIT_CLEAR_ALL)
|
||||
{
|
||||
ef->flags = 0;
|
||||
}
|
||||
|
||||
if (result.IsGood())
|
||||
{
|
||||
result = flags;
|
||||
return CELL_OK;
|
||||
}
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
Sleep(1);
|
||||
|
||||
if (counter++ > max_counter)
|
||||
{
|
||||
ef->waiters.invalidate(tid);
|
||||
return CELL_ETIMEDOUT;
|
||||
}
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
ConLog.Warning("sys_event_flag_wait(id=%d) aborted", eflag_id);
|
||||
return CELL_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int sys_event_flag_trywait(u32 eflag_id, u64 bitptn, u32 mode, mem64_t result)
|
||||
{
|
||||
sys_event_flag.Error("sys_event_flag_trywait(eflag_id=%d, bitptn=0x%llx, mode=0x%x, result_addr=0x%x)",
|
||||
sys_event_flag.Warning("sys_event_flag_trywait(eflag_id=%d, bitptn=0x%llx, mode=0x%x, result_addr=0x%x)",
|
||||
eflag_id, bitptn, mode, result.GetAddr());
|
||||
return CELL_OK;
|
||||
|
||||
if (result.IsGood()) result = 0;
|
||||
|
||||
switch (mode & 0xf)
|
||||
{
|
||||
case SYS_EVENT_FLAG_WAIT_AND: break;
|
||||
case SYS_EVENT_FLAG_WAIT_OR: break;
|
||||
default: return CELL_EINVAL;
|
||||
}
|
||||
|
||||
switch (mode & ~0xf)
|
||||
{
|
||||
case 0: break; // ???
|
||||
case SYS_EVENT_FLAG_WAIT_CLEAR: break;
|
||||
case SYS_EVENT_FLAG_WAIT_CLEAR_ALL: break;
|
||||
default: return CELL_EINVAL;
|
||||
}
|
||||
|
||||
event_flag* ef;
|
||||
if(!sys_event_flag.CheckId(eflag_id, ef)) return CELL_ESRCH;
|
||||
|
||||
SMutexLocker lock(ef->m_mutex);
|
||||
|
||||
u64 flags = ef->flags;
|
||||
|
||||
if (((mode & SYS_EVENT_FLAG_WAIT_AND) && (flags & bitptn) == bitptn) ||
|
||||
((mode & SYS_EVENT_FLAG_WAIT_OR) && (flags & bitptn)))
|
||||
{
|
||||
if (mode & SYS_EVENT_FLAG_WAIT_CLEAR)
|
||||
{
|
||||
ef->flags &= ~bitptn;
|
||||
}
|
||||
else if (mode & SYS_EVENT_FLAG_WAIT_CLEAR_ALL)
|
||||
{
|
||||
ef->flags = 0;
|
||||
}
|
||||
|
||||
if (result.IsGood())
|
||||
{
|
||||
result = flags;
|
||||
return CELL_OK;
|
||||
}
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
return CELL_EBUSY;
|
||||
}
|
||||
|
||||
int sys_event_flag_set(u32 eflag_id, u64 bitptn)
|
||||
@ -76,6 +196,7 @@ int sys_event_flag_set(u32 eflag_id, u64 bitptn)
|
||||
event_flag* ef;
|
||||
if(!sys_event_flag.CheckId(eflag_id, ef)) return CELL_ESRCH;
|
||||
|
||||
SMutexLocker lock(ef->m_mutex);
|
||||
ef->flags |= bitptn;
|
||||
|
||||
return CELL_OK;
|
||||
@ -88,6 +209,7 @@ int sys_event_flag_clear(u32 eflag_id, u64 bitptn)
|
||||
event_flag* ef;
|
||||
if(!sys_event_flag.CheckId(eflag_id, ef)) return CELL_ESRCH;
|
||||
|
||||
SMutexLocker lock(ef->m_mutex);
|
||||
ef->flags &= bitptn;
|
||||
|
||||
return CELL_OK;
|
||||
@ -96,6 +218,10 @@ int sys_event_flag_clear(u32 eflag_id, u64 bitptn)
|
||||
int sys_event_flag_cancel(u32 eflag_id, mem32_t num)
|
||||
{
|
||||
sys_event_flag.Error("sys_event_flag_cancel(eflag_id=%d, num_addr=0x%x)", eflag_id, num.GetAddr());
|
||||
|
||||
event_flag* ef;
|
||||
if(!sys_event_flag.CheckId(eflag_id, ef)) return CELL_ESRCH;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,12 @@ enum
|
||||
{
|
||||
SYS_SYNC_WAITER_SINGLE = 0x10000,
|
||||
SYS_SYNC_WAITER_MULTIPLE = 0x20000,
|
||||
|
||||
SYS_EVENT_FLAG_WAIT_AND = 0x01,
|
||||
SYS_EVENT_FLAG_WAIT_OR = 0x02,
|
||||
|
||||
SYS_EVENT_FLAG_WAIT_CLEAR = 0x10,
|
||||
SYS_EVENT_FLAG_WAIT_CLEAR_ALL = 0x20,
|
||||
};
|
||||
|
||||
struct sys_event_flag_attr
|
||||
@ -18,7 +24,9 @@ struct sys_event_flag_attr
|
||||
|
||||
struct event_flag
|
||||
{
|
||||
std::atomic<u64> flags;
|
||||
SMutex m_mutex;
|
||||
u64 flags;
|
||||
SleepQueue waiters;
|
||||
const u32 m_protocol;
|
||||
const int m_type;
|
||||
|
||||
|
@ -177,7 +177,7 @@ bool SleepQueue::invalidate(u32 tid)
|
||||
{
|
||||
if (list[i] = tid)
|
||||
{
|
||||
list[i] = 0;
|
||||
list.RemoveAt(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user