mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-04 11:47:13 +00:00
event flag improvement (not finished)
Fixed empty SPU thread name issue
This commit is contained in:
parent
475c3ff967
commit
c4d9223034
@ -896,9 +896,66 @@ public:
|
||||
SPU.In_MBox.PushUncond(CELL_OK);
|
||||
return;
|
||||
}
|
||||
else if (code = 128)
|
||||
{
|
||||
/* ===== sys_event_flag_set_bit ===== */
|
||||
u32 flag = v & 0xffffff;
|
||||
|
||||
u32 data;
|
||||
if (!SPU.Out_MBox.Pop(data))
|
||||
{
|
||||
ConLog.Error("sys_event_flag_set_bit(v=0x%x (flag=%d)): Out_MBox is empty", v, flag);
|
||||
return;
|
||||
}
|
||||
|
||||
if (flag > 63)
|
||||
{
|
||||
ConLog.Error("sys_event_flag_set_bit(id=%d, v=0x%x): flag > 63", data, v, flag);
|
||||
return;
|
||||
}
|
||||
|
||||
//if (Ini.HLELogging.GetValue())
|
||||
{
|
||||
ConLog.Warning("sys_event_flag_set_bit(id=%d, v=0x%x (flag=%d))", data, v, flag);
|
||||
}
|
||||
|
||||
EventFlag* ef;
|
||||
if (!Emu.GetIdManager().GetIDData(data, ef))
|
||||
{
|
||||
ConLog.Error("sys_event_flag_set_bit(id=%d, v=0x%x (flag=%d)): EventFlag not found", data, v, flag);
|
||||
SPU.In_MBox.PushUncond(CELL_ESRCH);
|
||||
return;
|
||||
}
|
||||
|
||||
u32 tid = GetCurrentCPUThread()->GetId();
|
||||
|
||||
ef->m_mutex.lock(tid);
|
||||
ef->flags |= (u64)1 << flag;
|
||||
if (u32 target = ef->check())
|
||||
{
|
||||
// if signal, leave both mutexes locked...
|
||||
ef->signal.lock(target);
|
||||
ef->m_mutex.unlock(tid, target);
|
||||
}
|
||||
else
|
||||
{
|
||||
ef->m_mutex.unlock(tid);
|
||||
}
|
||||
|
||||
SPU.In_MBox.PushUncond(CELL_OK);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
ConLog.Error("SPU_WrOutIntrMbox: unknown data (v=0x%x)", v);
|
||||
u32 data;
|
||||
if (SPU.Out_MBox.Pop(data))
|
||||
{
|
||||
ConLog.Error("SPU_WrOutIntrMbox: unknown data (v=0x%x); Out_MBox = 0x%x", v, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConLog.Error("SPU_WrOutIntrMbox: unknown data (v=0x%x)", v);
|
||||
}
|
||||
SPU.In_MBox.PushUncond(CELL_EINVAL); // ???
|
||||
return;
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ int sys_cond_signal(u32 cond_id)
|
||||
|
||||
if (u32 target = (mutex->protocol == SYS_SYNC_PRIORITY ? cond->m_queue.pop_prio() : cond->m_queue.pop()))
|
||||
{
|
||||
cond->cond.lock(target);
|
||||
cond->signal.lock(target);
|
||||
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
@ -99,7 +99,7 @@ int sys_cond_signal_all(u32 cond_id)
|
||||
|
||||
while (u32 target = (mutex->protocol == SYS_SYNC_PRIORITY ? cond->m_queue.pop_prio() : cond->m_queue.pop()))
|
||||
{
|
||||
cond->cond.lock(target);
|
||||
cond->signal.lock(target);
|
||||
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
@ -134,7 +134,7 @@ int sys_cond_signal_to(u32 cond_id, u32 thread_id)
|
||||
|
||||
u32 target = thread_id;
|
||||
{
|
||||
cond->cond.lock(target);
|
||||
cond->signal.lock(target);
|
||||
}
|
||||
|
||||
if (Emu.IsStopped())
|
||||
@ -173,11 +173,11 @@ int sys_cond_wait(u32 cond_id, u64 timeout)
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (cond->cond.GetOwner() == tid)
|
||||
if (cond->signal.GetOwner() == tid)
|
||||
{
|
||||
mutex->m_mutex.lock(tid);
|
||||
mutex->recursive = 1;
|
||||
cond->cond.unlock(tid);
|
||||
cond->signal.unlock(tid);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@ struct sys_cond_attribute
|
||||
struct Cond
|
||||
{
|
||||
Mutex* mutex; // associated with mutex
|
||||
SMutex cond;
|
||||
SMutex signal;
|
||||
SleepQueue m_queue;
|
||||
|
||||
Cond(Mutex* mutex, u64 name)
|
||||
|
@ -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.Log("sys_event_flag_create(eflag_id_addr=0x%x, attr_addr=0x%x, init=0x%llx)",
|
||||
sys_event_flag.Warning("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())
|
||||
@ -16,10 +16,10 @@ int sys_event_flag_create(mem32_t eflag_id, mem_ptr_t<sys_event_flag_attr> attr,
|
||||
|
||||
switch (attr->protocol.ToBE())
|
||||
{
|
||||
case se32(SYS_SYNC_PRIORITY): sys_event_flag.Warning("TODO: SYS_SYNC_PRIORITY attr"); break;
|
||||
case se32(SYS_SYNC_PRIORITY): break;
|
||||
case se32(SYS_SYNC_RETRY): sys_event_flag.Warning("TODO: SYS_SYNC_RETRY attr"); break;
|
||||
case se32(SYS_SYNC_PRIORITY_INHERIT): sys_event_flag.Warning("TODO: SYS_SYNC_PRIORITY_INHERIT attr"); break;
|
||||
case se32(SYS_SYNC_FIFO): sys_event_flag.Warning("TODO: SYS_SYNC_FIFO attr"); break;
|
||||
case se32(SYS_SYNC_FIFO): break;
|
||||
default: return CELL_EINVAL;
|
||||
}
|
||||
|
||||
@ -31,11 +31,11 @@ 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): break;
|
||||
case se32(SYS_SYNC_WAITER_MULTIPLE): sys_event_flag.Error("TODO: SYS_SYNC_WAITER_MULTIPLE type"); break;
|
||||
case se32(SYS_SYNC_WAITER_MULTIPLE): break;
|
||||
default: return CELL_EINVAL;
|
||||
}
|
||||
|
||||
eflag_id = sys_event_flag.GetNewId(new event_flag(init, (u32)attr->protocol, (int)attr->type));
|
||||
eflag_id = sys_event_flag.GetNewId(new EventFlag(init, (u32)attr->protocol, (int)attr->type));
|
||||
|
||||
sys_event_flag.Warning("*** event_flag created [%s] (protocol=0x%x, type=0x%x): id = %d",
|
||||
wxString(attr->name, 8).wx_str(), (u32)attr->protocol, (int)attr->type, eflag_id.GetValue());
|
||||
@ -47,9 +47,14 @@ int sys_event_flag_destroy(u32 eflag_id)
|
||||
{
|
||||
sys_event_flag.Warning("sys_event_flag_destroy(eflag_id=%d)", eflag_id);
|
||||
|
||||
event_flag* ef;
|
||||
EventFlag* ef;
|
||||
if(!sys_event_flag.CheckId(eflag_id, ef)) return CELL_ESRCH;
|
||||
|
||||
if (ef->waiters.GetCount()) // ???
|
||||
{
|
||||
return CELL_EBUSY;
|
||||
}
|
||||
|
||||
Emu.GetIdManager().RemoveID(eflag_id);
|
||||
|
||||
return CELL_OK;
|
||||
@ -77,16 +82,50 @@ int sys_event_flag_wait(u32 eflag_id, u64 bitptn, u32 mode, mem64_t result, u64
|
||||
default: return CELL_EINVAL;
|
||||
}
|
||||
|
||||
event_flag* ef;
|
||||
EventFlag* 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;
|
||||
SMutexLocker lock(ef->m_mutex);
|
||||
if (ef->m_type == SYS_SYNC_WAITER_SINGLE && ef->waiters.GetCount() > 0)
|
||||
{
|
||||
return CELL_EPERM;
|
||||
}
|
||||
EventFlagWaiter rec;
|
||||
rec.bitptn = bitptn;
|
||||
rec.mode = mode;
|
||||
rec.tid = tid;
|
||||
ef->waiters.AddCpy(rec);
|
||||
|
||||
if (ef->check() == tid)
|
||||
{
|
||||
u64 flags = ef->flags;
|
||||
|
||||
ef->waiters.RemoveAt(ef->waiters.GetCount() - 1);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (!result.GetAddr())
|
||||
{
|
||||
return CELL_OK;
|
||||
}
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
u32 counter = 0;
|
||||
@ -94,39 +133,61 @@ int sys_event_flag_wait(u32 eflag_id, u64 bitptn, u32 mode, mem64_t result, u64
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (ef->signal.GetOwner() == tid)
|
||||
{
|
||||
SMutexLocker lock(ef->m_mutex);
|
||||
|
||||
ef->signal.unlock(tid);
|
||||
|
||||
u64 flags = ef->flags;
|
||||
|
||||
if (((mode & SYS_EVENT_FLAG_WAIT_AND) && (flags & bitptn) == bitptn) ||
|
||||
((mode & SYS_EVENT_FLAG_WAIT_OR) && (flags & bitptn)))
|
||||
for (u32 i = 0; i < ef->waiters.GetCount(); i++)
|
||||
{
|
||||
ef->waiters.invalidate(tid);
|
||||
if (ef->waiters[i].tid == tid)
|
||||
{
|
||||
ef->waiters.RemoveAt(i);
|
||||
|
||||
if (mode & SYS_EVENT_FLAG_WAIT_CLEAR)
|
||||
{
|
||||
ef->flags &= ~bitptn;
|
||||
}
|
||||
else if (mode & SYS_EVENT_FLAG_WAIT_CLEAR_ALL)
|
||||
{
|
||||
ef->flags = 0;
|
||||
}
|
||||
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;
|
||||
if (result.IsGood())
|
||||
{
|
||||
result = flags;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
if (!result.GetAddr())
|
||||
{
|
||||
return CELL_OK;
|
||||
}
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
return CELL_ECANCELED;
|
||||
}
|
||||
|
||||
Sleep(1);
|
||||
|
||||
if (counter++ > max_counter)
|
||||
{
|
||||
ef->waiters.invalidate(tid);
|
||||
SMutexLocker lock(ef->m_mutex);
|
||||
|
||||
for (u32 i = 0; i < ef->waiters.GetCount(); i++)
|
||||
{
|
||||
if (ef->waiters[i].tid == tid)
|
||||
{
|
||||
ef->waiters.RemoveAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return CELL_ETIMEDOUT;
|
||||
}
|
||||
if (Emu.IsStopped())
|
||||
@ -159,7 +220,7 @@ int sys_event_flag_trywait(u32 eflag_id, u64 bitptn, u32 mode, mem64_t result)
|
||||
default: return CELL_EINVAL;
|
||||
}
|
||||
|
||||
event_flag* ef;
|
||||
EventFlag* ef;
|
||||
if(!sys_event_flag.CheckId(eflag_id, ef)) return CELL_ESRCH;
|
||||
|
||||
SMutexLocker lock(ef->m_mutex);
|
||||
@ -183,6 +244,11 @@ int sys_event_flag_trywait(u32 eflag_id, u64 bitptn, u32 mode, mem64_t result)
|
||||
result = flags;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
if (!result.GetAddr())
|
||||
{
|
||||
return CELL_OK;
|
||||
}
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
@ -193,11 +259,23 @@ int sys_event_flag_set(u32 eflag_id, u64 bitptn)
|
||||
{
|
||||
sys_event_flag.Warning("sys_event_flag_set(eflag_id=%d, bitptn=0x%llx)", eflag_id, bitptn);
|
||||
|
||||
event_flag* ef;
|
||||
EventFlag* ef;
|
||||
if(!sys_event_flag.CheckId(eflag_id, ef)) return CELL_ESRCH;
|
||||
|
||||
SMutexLocker lock(ef->m_mutex);
|
||||
u32 tid = GetCurrentPPUThread().GetId();
|
||||
|
||||
ef->m_mutex.lock(tid);
|
||||
ef->flags |= bitptn;
|
||||
if (u32 target = ef->check())
|
||||
{
|
||||
// if signal, leave both mutexes locked...
|
||||
ef->signal.lock(target);
|
||||
ef->m_mutex.unlock(tid, target);
|
||||
}
|
||||
else
|
||||
{
|
||||
ef->m_mutex.unlock(tid);
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -206,7 +284,7 @@ int sys_event_flag_clear(u32 eflag_id, u64 bitptn)
|
||||
{
|
||||
sys_event_flag.Warning("sys_event_flag_clear(eflag_id=%d, bitptn=0x%llx)", eflag_id, bitptn);
|
||||
|
||||
event_flag* ef;
|
||||
EventFlag* ef;
|
||||
if(!sys_event_flag.CheckId(eflag_id, ef)) return CELL_ESRCH;
|
||||
|
||||
SMutexLocker lock(ef->m_mutex);
|
||||
@ -217,27 +295,61 @@ 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());
|
||||
sys_event_flag.Warning("sys_event_flag_cancel(eflag_id=%d, num_addr=0x%x)", eflag_id, num.GetAddr());
|
||||
|
||||
event_flag* ef;
|
||||
EventFlag* ef;
|
||||
if(!sys_event_flag.CheckId(eflag_id, ef)) return CELL_ESRCH;
|
||||
|
||||
return CELL_OK;
|
||||
Array<u32> tids;
|
||||
|
||||
{
|
||||
SMutexLocker lock(ef->m_mutex);
|
||||
tids.SetCount(ef->waiters.GetCount());
|
||||
for (u32 i = 0; i < ef->waiters.GetCount(); i++)
|
||||
{
|
||||
tids[i] = ef->waiters[i].tid;
|
||||
}
|
||||
ef->waiters.Clear();
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < tids.GetCount(); i++)
|
||||
{
|
||||
if (Emu.IsStopped()) break;
|
||||
ef->signal.lock(tids[i]);
|
||||
}
|
||||
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
ConLog.Warning("sys_event_flag_cancel(id=%d) aborted", eflag_id);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
if (num.IsGood())
|
||||
{
|
||||
num = tids.GetCount();
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
if (!num.GetAddr())
|
||||
{
|
||||
return CELL_OK;
|
||||
}
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
int sys_event_flag_get(u32 eflag_id, mem64_t flags)
|
||||
{
|
||||
sys_event_flag.Warning("sys_event_flag_get(eflag_id=%d, flags_addr=0x%x)", eflag_id, flags.GetAddr());
|
||||
|
||||
EventFlag* ef;
|
||||
if(!sys_event_flag.CheckId(eflag_id, ef)) return CELL_ESRCH;
|
||||
|
||||
if (!flags.IsGood())
|
||||
{
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
event_flag* ef;
|
||||
if(!sys_event_flag.CheckId(eflag_id, ef)) return CELL_ESRCH;
|
||||
|
||||
flags = ef->flags;
|
||||
flags = ef->flags; // ???
|
||||
|
||||
return CELL_OK;
|
||||
}
|
@ -22,18 +22,54 @@ struct sys_event_flag_attr
|
||||
char name[8];
|
||||
};
|
||||
|
||||
struct event_flag
|
||||
struct EventFlagWaiter
|
||||
{
|
||||
u32 tid;
|
||||
u32 mode;
|
||||
u64 bitptn;
|
||||
};
|
||||
|
||||
struct EventFlag
|
||||
{
|
||||
SMutex m_mutex;
|
||||
u64 flags;
|
||||
SleepQueue waiters;
|
||||
Array<EventFlagWaiter> waiters;
|
||||
SMutex signal;
|
||||
const u32 m_protocol;
|
||||
const int m_type;
|
||||
|
||||
event_flag(u64 pattern, u32 protocol, int type)
|
||||
EventFlag(u64 pattern, u32 protocol, int type)
|
||||
: flags(pattern)
|
||||
, m_protocol(protocol)
|
||||
, m_type(type)
|
||||
{
|
||||
}
|
||||
|
||||
u32 check()
|
||||
{
|
||||
SleepQueue sq; // TODO: implement without SleepQueue
|
||||
|
||||
u32 target = 0;
|
||||
|
||||
for (u32 i = 0; i < waiters.GetCount(); i++)
|
||||
{
|
||||
if (((waiters[i].mode & SYS_EVENT_FLAG_WAIT_AND) && (flags & waiters[i].bitptn) == waiters[i].bitptn) ||
|
||||
((waiters[i].mode & SYS_EVENT_FLAG_WAIT_OR) && (flags & waiters[i].bitptn)))
|
||||
{
|
||||
if (m_protocol == SYS_SYNC_FIFO)
|
||||
{
|
||||
target = waiters[i].tid;
|
||||
break;
|
||||
}
|
||||
sq.list.AddCpy(waiters[i].tid);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_protocol == SYS_SYNC_PRIORITY)
|
||||
{
|
||||
target = sq.pop_prio();
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
};
|
@ -83,9 +83,12 @@ int sys_spu_thread_initialize(mem32_t thread, u32 group, u32 spu_num, mem_ptr_t<
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
if(!Memory.IsGoodAddr(attr->name_addr, attr->name_len))
|
||||
if (attr->name_addr)
|
||||
{
|
||||
return CELL_EFAULT;
|
||||
if(!Memory.IsGoodAddr(attr->name_addr, attr->name_len))
|
||||
{
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
if(spu_num >= group_info->list.GetCount())
|
||||
@ -99,7 +102,13 @@ int sys_spu_thread_initialize(mem32_t thread, u32 group, u32 spu_num, mem_ptr_t<
|
||||
}
|
||||
|
||||
u32 spu_ep = (u32)img->entry_point;
|
||||
std::string name = Memory.ReadString(attr->name_addr, attr->name_len).ToStdString();
|
||||
|
||||
std::string name = "SPUThread";
|
||||
if (attr->name_addr)
|
||||
{
|
||||
name = Memory.ReadString(attr->name_addr, attr->name_len).ToStdString();
|
||||
}
|
||||
|
||||
u64 a1 = arg->arg1;
|
||||
u64 a2 = arg->arg2;
|
||||
u64 a3 = arg->arg3;
|
||||
@ -123,7 +132,7 @@ int sys_spu_thread_initialize(mem32_t thread, u32 group, u32 spu_num, mem_ptr_t<
|
||||
(*(SPUThread*)&new_thread).group = group_info;
|
||||
|
||||
sc_spu.Warning("*** New SPU Thread [%s] (img_offset=0x%x, ls_offset=0x%x, ep=0x%x, a1=0x%llx, a2=0x%llx, a3=0x%llx, a4=0x%llx): id=%d",
|
||||
wxString(name).wx_str(), (u32)img->segs_addr, ((SPUThread&)new_thread).dmac.ls_offset, spu_ep, a1, a2, a3, a4, thread.GetValue());
|
||||
wxString(attr->name_addr ? name : "").wx_str(), (u32)img->segs_addr, ((SPUThread&)new_thread).dmac.ls_offset, spu_ep, a1, a2, a3, a4, thread.GetValue());
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user