diff --git a/Utilities/SMutex.h b/Utilities/SMutex.h index 6566b235d3..ac5ec269e8 100644 --- a/Utilities/SMutex.h +++ b/Utilities/SMutex.h @@ -126,7 +126,11 @@ public: : sm(_sm) , tid(get_tid()) { - if (!tid) throw "SMutexLockerBase: invalid thread id"; + if (!tid) + { + ConLog.Error("SMutexLockerBase: thread id == 0"); + Emu.Pause(); + } sm.lock(tid); } diff --git a/rpcs3/Emu/CPU/CPUThread.h b/rpcs3/Emu/CPU/CPUThread.h index b4f2e90b84..4010adc7c5 100644 --- a/rpcs3/Emu/CPU/CPUThread.h +++ b/rpcs3/Emu/CPU/CPUThread.h @@ -9,12 +9,13 @@ struct reservation_struct volatile u32 owner; // id of thread that got reservation volatile u32 addr; volatile u32 size; + volatile u32 data32; + volatile u64 data64; + // atm, PPU can't break SPU MFC reservation correctly __forceinline void clear() { owner = 0; - addr = 0; - size = 0; } }; diff --git a/rpcs3/Emu/Cell/PPUInterpreter.h b/rpcs3/Emu/Cell/PPUInterpreter.h index 3277b9c446..7985b57b28 100644 --- a/rpcs3/Emu/Cell/PPUInterpreter.h +++ b/rpcs3/Emu/Cell/PPUInterpreter.h @@ -2361,14 +2361,13 @@ private: } void LWARX(u32 rd, u32 ra, u32 rb) { - ConLog.Warning("LWARX"); const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; SMutexLocker lock(reservation.mutex); reservation.owner = lock.tid; reservation.addr = addr; reservation.size = 4; - CPU.GPR[rd] = Memory.Read32(addr); + reservation.data32 = CPU.GPR[rd] = Memory.Read32(addr); } void LDX(u32 rd, u32 ra, u32 rb) { @@ -2538,14 +2537,13 @@ private: } void LDARX(u32 rd, u32 ra, u32 rb) { - ConLog.Warning("LDARX"); const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; SMutexLocker lock(reservation.mutex); reservation.owner = lock.tid; reservation.addr = addr; reservation.size = 8; - CPU.GPR[rd] = Memory.Read64(addr); + reservation.data64 = CPU.GPR[rd] = Memory.Read64(addr); } void DCBF(u32 ra, u32 rb) { @@ -2658,14 +2656,13 @@ private: } void STWCX_(u32 rs, u32 ra, u32 rb) { - ConLog.Warning("STWCX_"); const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; SMutexLocker lock(reservation.mutex); if (lock.tid == reservation.owner && reservation.addr == addr && reservation.size == 4) { - Memory.Write32(addr, CPU.GPR[rs]); - CPU.SetCR_EQ(0, true); + // Memory.Write32(addr, CPU.GPR[rs]); + CPU.SetCR_EQ(0, InterlockedCompareExchange((volatile long*)(Memory + addr), (u32)CPU.GPR[rs], reservation.data32) == reservation.data32); reservation.clear(); } else @@ -2712,14 +2709,13 @@ private: } void STDCX_(u32 rs, u32 ra, u32 rb) { - ConLog.Warning("STDCX_"); const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; SMutexLocker lock(reservation.mutex); if (lock.tid == reservation.owner && reservation.addr == addr && reservation.size == 8) { - Memory.Write64(addr, CPU.GPR[rs]); - CPU.SetCR_EQ(0, true); + // Memory.Write64(addr, CPU.GPR[rs]); + CPU.SetCR_EQ(0, InterlockedCompareExchange64((volatile long long*)(Memory + addr), CPU.GPR[rs], reservation.data64) == reservation.data64); reservation.clear(); } else diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp index 118abc319a..2cdafe3fe0 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp @@ -83,7 +83,7 @@ struct CellAudioPortConfig struct CellAudioConfig //custom structure { bool m_is_audio_initialized; - bool m_is_audio_port_open; + bool m_is_audio_port_opened; bool m_is_audio_port_started; }; @@ -216,7 +216,7 @@ int cellAudioPortOpen(mem_ptr_t audioParam, mem32_t portNum) cellAudio.Warning("cellAudioPortOpen(audioParam_addr=0x%x,portNum_addr=0x%x)",audioParam.GetAddr(),portNum.GetAddr()); if(!audioParam.IsGood() || !portNum.IsGood()) return CELL_AUDIO_ERROR_PORT_OPEN; - m_config->m_is_audio_port_open = true; + m_config->m_is_audio_port_opened = true; m_param->nChannel = audioParam->nChannel; m_param->nBlock = audioParam->nBlock; @@ -238,13 +238,13 @@ int cellAudioGetPortConfig(u32 portNum, mem_ptr_t portConfi //if(portNum > 7) return CELL_AUDIO_ERROR_PORT_FULL; - if(m_config->m_is_audio_port_open == false) + if(!m_config->m_is_audio_port_opened) { portConfig->status = CELL_AUDIO_STATUS_CLOSE; return CELL_OK; } - if(m_config->m_is_audio_port_started == true) + if(m_config->m_is_audio_port_started) { portConfig->status = CELL_AUDIO_STATUS_RUN; } @@ -268,7 +268,7 @@ int cellAudioPortStart(u32 portNum) { cellAudio.Warning("cellAudioPortStart(portNum=0x%x)",portNum); - if (m_config->m_is_audio_port_open == true) + if (!m_config->m_is_audio_port_opened) return CELL_AUDIO_ERROR_PORT_OPEN; m_config->m_is_audio_port_started = true; @@ -279,10 +279,10 @@ int cellAudioPortClose(u32 portNum) { cellAudio.Warning("cellAudioPortClose(portNum=0x%x)",portNum); - if (m_config->m_is_audio_port_open == false) + if (!m_config->m_is_audio_port_opened) return CELL_AUDIO_ERROR_PORT_NOT_OPEN; - m_config->m_is_audio_port_open = false; + m_config->m_is_audio_port_opened = false; return CELL_OK; } @@ -1016,6 +1016,6 @@ void cellAudio_init() void cellAudio_unload() { m_config->m_is_audio_initialized = false; - m_config->m_is_audio_port_open = false; + m_config->m_is_audio_port_opened = false; m_config->m_is_audio_port_started = false; } \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/SysCalls.h b/rpcs3/Emu/SysCalls/SysCalls.h index 4797f57270..c40a4a8d01 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.h +++ b/rpcs3/Emu/SysCalls/SysCalls.h @@ -127,7 +127,7 @@ extern int sys_game_process_exitspawn(u32 path_addr, u32 argv_addr, u32 envp_add u32 data, u32 data_size, int prio, u64 flags ); //sys_event -extern int sys_event_queue_create(u32 equeue_id_addr, u32 attr_addr, u64 event_queue_key, int size); +extern int sys_event_queue_create(mem32_t equeue_id, mem_ptr_t attr, u64 event_queue_key, int size); extern int sys_event_queue_receive(u32 equeue_id, u32 event_addr, u32 timeout); extern int sys_event_port_create(u32 eport_id_addr, int port_type, u64 name); extern int sys_event_port_connect_local(u32 event_port_id, u32 event_queue_id); diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Event.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Event.cpp index be08331641..357f8cbfcf 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Event.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Event.cpp @@ -6,30 +6,24 @@ SysCallBase sys_event("sys_event"); //128 -int sys_event_queue_create(u32 equeue_id_addr, u32 attr_addr, u64 event_queue_key, int size) +int sys_event_queue_create(mem32_t equeue_id, mem_ptr_t attr, u64 event_queue_key, int size) { sys_event.Warning("sys_event_queue_create(equeue_id_addr=0x%x, attr_addr=0x%x, event_queue_key=0x%llx, size=%d)", - equeue_id_addr, attr_addr, event_queue_key, size); + equeue_id.GetAddr(), attr.GetAddr(), event_queue_key, size); if(size <= 0 || size > 127) { return CELL_EINVAL; } - if(!Memory.IsGoodAddr(equeue_id_addr, 4) || !Memory.IsGoodAddr(attr_addr, sizeof(sys_event_queue_attr))) + if(!equeue_id.IsGood() || !attr.IsGood()) { return CELL_EFAULT; } - auto& attr = (sys_event_queue_attr&)Memory[attr_addr]; - sys_event.Warning("name = %s", attr.name); - sys_event.Warning("type = %d", re(attr.type)); - EventQueue* equeue = new EventQueue(); - equeue->size = size; - equeue->pos = 0; - equeue->type = re(attr.type); - strncpy(equeue->name, attr.name, 8); - Memory.Write32(equeue_id_addr, sys_event.GetNewId(equeue)); + equeue_id = sys_event.GetNewId(new EventQueue((u32)attr->protocol, (int)attr->type, attr->name_u64, event_queue_key, size)); + sys_event.Warning("*** event_queue created[%s] (protocol=0x%x, type=0x%x): id = %d", + attr->name, (u32)attr->protocol, (int)attr->type, equeue_id.GetValue()); return CELL_OK; } @@ -79,10 +73,10 @@ int sys_event_queue_receive(u32 equeue_id, u32 event_addr, u32 timeout) { auto dst = (sys_event_data&)Memory[event_addr]; - re(dst.source, equeue->ports[i]->name); - re(dst.data1, equeue->ports[i]->data1); - re(dst.data2, equeue->ports[i]->data2); - re(dst.data3, equeue->ports[i]->data3); + dst.source = equeue->ports[i]->name; + dst.data1 = equeue->ports[i]->data1; + dst.data2 = equeue->ports[i]->data2; + dst.data3 = equeue->ports[i]->data3; equeue->ports[i]->has_data = false; diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Lwcond.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Lwcond.cpp index 9dbcef51e6..33da310eea 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Lwcond.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Lwcond.cpp @@ -7,24 +7,16 @@ SysCallBase sys_lwcond("sys_lwcond"); int sys_lwcond_create(mem_ptr_t lwcond, mem_ptr_t lwmutex, mem_ptr_t attr) { - sys_lwcond.Warning("sys_lwcond_create(lwcond_addr=0x%x, lwmutex_addr=0x%x, attr_addr=0x%x)", + sys_lwcond.Log("sys_lwcond_create(lwcond_addr=0x%x, lwmutex_addr=0x%x, attr_addr=0x%x)", lwcond.GetAddr(), lwmutex.GetAddr(), attr.GetAddr()); if (!lwcond.IsGood() || !lwmutex.IsGood() || !attr.IsGood()) return CELL_EFAULT; - switch (lwmutex->attribute.ToBE()) - { - case se32(SYS_SYNC_PRIORITY): break; - case se32(SYS_SYNC_RETRY): sys_lwcond.Error("Invalid SYS_SYNC_RETRY attr"); break; - case se32(SYS_SYNC_PRIORITY_INHERIT): sys_lwcond.Warning("TODO: SYS_SYNC_PRIORITY_INHERIT attr"); break; - case se32(SYS_SYNC_FIFO): break; - default: sys_lwcond.Error("Invalid lwmutex protocol(%d)", (u32)lwmutex->attribute); break; - } + lwcond->lwmutex = lwmutex.GetAddr(); + lwcond->lwcond_queue = sys_lwcond.GetNewId(new LWCond(attr->name_u64)); - lwcond->lwmutex_addr = lwmutex.GetAddr(); - lwcond->lwcond_queue = sys_lwcond.GetNewId(new LWCond((u32)lwmutex->attribute, *(u64*)&attr->name)); - - sys_lwcond.Warning("*** lwcond created [%s] (protocol=0x%x): id=%d", attr->name, (u32)lwmutex->attribute, (u32)lwcond->lwcond_queue); + sys_lwcond.Warning("*** lwcond created [%s] (attr=0x%x, lwmutex.sq=0x%x): id=0x%x", + attr->name, (u32)lwmutex->attribute, (u32)lwmutex->sleep_queue, (u32)lwcond->lwcond_queue); return CELL_OK; } @@ -50,7 +42,7 @@ int sys_lwcond_signal(mem_ptr_t lwcond) u32 id = (u32)lwcond->lwcond_queue; if (!sys_lwcond.CheckId(id, lwc)) return CELL_ESRCH; - lwc->signal(); + lwc->signal(mem_ptr_t(lwcond->lwmutex)->attribute); return CELL_OK; } @@ -92,7 +84,8 @@ int sys_lwcond_wait(mem_ptr_t lwcond, u64 timeout) u32 id = (u32)lwcond->lwcond_queue; if (!sys_lwcond.CheckId(id, lwc)) return CELL_ESRCH; const u32 tid = GetCurrentPPUThread().GetId(); - mem_ptr_t lwmutex((u32)lwcond->lwmutex_addr); + + mem_ptr_t lwmutex(lwcond->lwmutex); if ((u32)lwmutex->owner.GetOwner() != tid) return CELL_EPERM; // caller must own this lwmutex lwc->begin_waiting(tid); diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Lwcond.h b/rpcs3/Emu/SysCalls/lv2/SC_Lwcond.h index c72347e3b3..037f47f67b 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Lwcond.h +++ b/rpcs3/Emu/SysCalls/lv2/SC_Lwcond.h @@ -2,12 +2,16 @@ struct sys_lwcond_attribute_t { - char name[8]; + union + { + char name[8]; + u64 name_u64; + }; }; struct sys_lwcond_t { - be_t lwmutex_addr; + be_t lwmutex; be_t lwcond_queue; }; @@ -18,22 +22,20 @@ struct LWCond std::mutex m_lock; Array waiters; // list of waiting threads Array signaled; // list of signaled threads - u32 m_protocol; // protocol u64 m_name; // not used - LWCond(u32 prot, u64 name) + LWCond(u64 name) : m_name(name) - , m_protocol(prot) { } - void signal() + void signal(u32 _protocol) { std::lock_guard lock(m_lock); if (waiters.GetCount()) { - if (m_protocol == SYS_SYNC_PRIORITY) + if ((_protocol & SYS_SYNC_ATTR_PROTOCOL_MASK) == SYS_SYNC_PRIORITY) { u64 max_prio = 0; u32 sel = 0; diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp index 64ee82f42b..386e99f5f9 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp @@ -7,7 +7,7 @@ SysCallBase sc_lwmutex("sys_lwmutex"); int sys_lwmutex_create(mem_ptr_t lwmutex, mem_ptr_t attr) { - sc_lwmutex.Warning("sys_lwmutex_create(lwmutex_addr=0x%x, lwmutex_attr_addr=0x%x)", + sc_lwmutex.Log("sys_lwmutex_create(lwmutex_addr=0x%x, lwmutex_attr_addr=0x%x)", lwmutex.GetAddr(), attr.GetAddr()); if (!lwmutex.IsGood() || !attr.IsGood()) return CELL_EFAULT; @@ -16,40 +16,49 @@ int sys_lwmutex_create(mem_ptr_t lwmutex, mem_ptr_tattr_recursive); return CELL_EINVAL; } switch (attr->attr_protocol.ToBE()) { - case se32(SYS_SYNC_PRIORITY): sc_lwmutex.Warning("TODO: SYS_SYNC_PRIORITY attr"); break; + case se32(SYS_SYNC_PRIORITY): break; case se32(SYS_SYNC_RETRY): break; - case se32(SYS_SYNC_PRIORITY_INHERIT): sc_lwmutex.Error("Invalid SYS_SYNC_PRIORITY_INHERIT attr"); break; - case se32(SYS_SYNC_FIFO): sc_lwmutex.Warning("TODO: SYS_SYNC_FIFO attr"); break; - default: return CELL_EINVAL; + 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; } - lwmutex->attribute = (u32)attr->attr_protocol | (u32)attr->attr_recursive; + lwmutex->attribute = attr->attr_protocol | attr->attr_recursive; lwmutex->all_info = 0; lwmutex->pad = 0; lwmutex->recursive_count = 0; - lwmutex->sleep_queue = 0; - sc_lwmutex.Warning("*** lwmutex created [%s] (attribute=0x%x): id=???", attr->name, (u32)lwmutex->attribute); + 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); return CELL_OK; } int sys_lwmutex_destroy(mem_ptr_t lwmutex) { - sc_lwmutex.Warning("sys_lwmutex_destroy(lwmutex_addr=0x%x)", lwmutex.GetAddr()); + sc_lwmutex.Log("sys_lwmutex_destroy(lwmutex_addr=0x%x)", lwmutex.GetAddr()); if (!lwmutex.IsGood()) return CELL_EFAULT; + u32 sq_id = lwmutex->sleep_queue; + if (!Emu.GetIdManager().CheckID(sq_id)) return CELL_ESRCH; + // try to make it unable to lock switch (int res = lwmutex->trylock(~0)) { - case CELL_OK: lwmutex->attribute = 0; - default: return res; + case CELL_OK: + lwmutex->attribute = 0; + lwmutex->sleep_queue = 0; + Emu.GetIdManager().RemoveID(sq_id); + default: return res; } } diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.h b/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.h index df75462edc..7275724b08 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.h +++ b/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.h @@ -31,7 +31,103 @@ struct sys_lwmutex_attribute_t { be_t attr_protocol; be_t attr_recursive; - char name[8]; + union + { + char name[8]; + u64 name_u64; + }; +}; + +class SleepQueue +{ + /* struct q_rec + { + u32 tid; + u64 prio; + q_rec(u32 tid, u64 prio): tid(tid), prio(prio) {} + }; */ + + SMutex m_mutex; + Array list; + u64 m_name; + +public: + SleepQueue(u64 name) + : m_name(name) + { + } + + void push(u32 tid) + { + SMutexLocker lock(m_mutex); + list.AddCpy(tid); + } + + u32 pop() // SYS_SYNC_FIFO + { + SMutexLocker lock(m_mutex); + + while (true) + { + if (list.GetCount()) + { + u32 res = list[0]; + list.RemoveAt(0); + if (Emu.GetIdManager().CheckID(res)) + // check thread + { + return res; + } + } + return 0; + }; + } + + u32 pop_prio() // SYS_SYNC_PRIORITY + { + SMutexLocker lock(m_mutex); + + while (true) + { + if (list.GetCount()) + { + u64 max_prio = 0; + u32 sel = 0; + for (u32 i = 0; i < list.GetCount(); i++) + { + CPUThread* t = Emu.GetCPU().GetThread(list[i]); + if (!t) + { + list[i] = 0; + sel = i; + break; + } + + u64 prio = t->GetPrio(); + if (prio > max_prio) + { + max_prio = prio; + sel = i; + } + } + u32 res = list[sel]; + list.RemoveAt(sel); + /* if (Emu.GetIdManager().CheckID(res)) */ + if (res) + // check thread + { + return res; + } + } + return 0; + } + } + + u32 pop_prio_inherit() // (TODO) + { + ConLog.Error("TODO: SleepQueue::pop_prio_inherit()"); + Emu.Pause(); + } }; struct sys_lwmutex_t @@ -53,16 +149,16 @@ struct sys_lwmutex_t be_t sleep_queue; be_t pad; - int enter(u32 tid) // check and process (non-)recursive mutex + int trylock(be_t tid) { - if (!attribute) return CELL_EINVAL; + if (!attribute.ToBE()) return CELL_EINVAL; - if (tid == (u32)owner.GetOwner()) + if (tid == owner.GetOwner()) { if (attribute.ToBE() & se32(SYS_SYNC_RECURSIVE)) { recursive_count += 1; - if (!recursive_count) return CELL_EKRESOURCE; + if (!recursive_count.ToBE()) return CELL_EKRESOURCE; return CELL_OK; } else @@ -70,52 +166,64 @@ struct sys_lwmutex_t return CELL_EDEADLK; } } - return CELL_EBUSY; - } - int trylock(u32 tid) - { - switch (int res = enter(tid)) - { - case CELL_EBUSY: break; - default: return res; - } switch (owner.trylock(tid)) { - case SMR_OK: recursive_count = 1; return CELL_OK; - default: return CELL_EBUSY; + case SMR_OK: recursive_count = 1; return CELL_OK; + case SMR_FAILED: return CELL_EBUSY; + default: return CELL_EINVAL; } } - int unlock(u32 tid) + int unlock(be_t tid) { - if (tid != (u32)owner.GetOwner()) + if (tid != owner.GetOwner()) { return CELL_EPERM; } else { recursive_count -= 1; - if (!recursive_count) + if (!recursive_count.ToBE()) { - owner.unlock(tid); + be_t target = 0; + switch (attribute.ToBE() & se32(SYS_SYNC_ATTR_PROTOCOL_MASK)) + { + case se32(SYS_SYNC_FIFO): + case se32(SYS_SYNC_PRIORITY): + SleepQueue* sq; + if (!Emu.GetIdManager().GetIDData(sleep_queue, sq)) return CELL_ESRCH; + target = attribute.ToBE() & se32(SYS_SYNC_FIFO) ? sq->pop() : sq->pop_prio(); + case se32(SYS_SYNC_RETRY): default: owner.unlock(tid, target); break; + } } return CELL_OK; } } - int lock(u32 tid, u64 timeout) + int lock(be_t tid, u64 timeout) { - switch (int res = enter(tid)) + switch (int res = trylock(tid)) { - case CELL_EBUSY: break; - default: return res; + case CELL_EBUSY: break; + default: return res; } + + switch (attribute.ToBE() & se32(SYS_SYNC_ATTR_PROTOCOL_MASK)) + { + case se32(SYS_SYNC_PRIORITY): + case se32(SYS_SYNC_FIFO): + SleepQueue* sq; + if (!Emu.GetIdManager().GetIDData(sleep_queue, sq)) return CELL_ESRCH; + sq->push(tid); + default: break; + } + switch (owner.lock(tid, timeout)) { - case SMR_OK: recursive_count = 1; return CELL_OK; - case SMR_TIMEOUT: return CELL_ETIMEDOUT; - default: return CELL_EINVAL; + case SMR_OK: case SMR_SIGNAL: recursive_count = 1; return CELL_OK; + case SMR_TIMEOUT: return CELL_ETIMEDOUT; + default: return CELL_EINVAL; } } }; @@ -123,13 +231,17 @@ struct sys_lwmutex_t class lwmutex_locker { mem_ptr_t m_mutex; - u32 m_id; + be_t m_id; - lwmutex_locker(u32 lwmutex_addr, u32 tid, u64 timeout = 0) + lwmutex_locker(mem_ptr_t lwmutex, be_t tid, u64 timeout = 0) : m_id(tid) - , m_mutex(lwmutex_addr) + , m_mutex(lwmutex) { - if (int res = m_mutex->lock(m_id, timeout)) throw "lwmutex_locker: m_mutex->lock failed"; + if (int res = m_mutex->lock(m_id, timeout)) + { + ConLog.Error("lwmutex_locker: m_mutex->lock failed(res=0x%x)", res); + Emu.Pause(); + } } ~lwmutex_locker() diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Rwlock.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Rwlock.cpp index c86afcd372..d07ab05677 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Rwlock.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Rwlock.cpp @@ -21,11 +21,11 @@ int sys_rwlock_create(mem32_t rw_lock_id, mem_ptr_t attr if (attr->attr_pshared.ToBE() != se32(0x200)) { + sys_rwlock.Error("Invalid attr_pshared(0x%x)", (u32)attr->attr_pshared); return CELL_EINVAL; } - rw_lock_id = sys_rwlock.GetNewId(new RWLock((u32)attr->attr_protocol, (u32)attr->attr_pshared, - (u64)attr->key, (s32)attr->flags, *(u64*)&attr->name)); + rw_lock_id = sys_rwlock.GetNewId(new RWLock((u32)attr->attr_protocol, attr->name_u64)); sys_rwlock.Warning("*** rwlock created [%s] (protocol=0x%x): id=%d", attr->name, (u32)attr->attr_protocol, rw_lock_id.GetValue()); diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Rwlock.h b/rpcs3/Emu/SysCalls/lv2/SC_Rwlock.h index 720f137db7..dc9c563b6d 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Rwlock.h +++ b/rpcs3/Emu/SysCalls/lv2/SC_Rwlock.h @@ -6,8 +6,12 @@ struct sys_rwlock_attribute_t be_t attr_pshared; // == 0x200 (NOT SHARED) be_t key; // process-shared key (not used) be_t flags; // process-shared flags (not used) - be_t pad; - char name[8]; + be_t pad; // not used + union + { + char name[8]; + u64 name_u64; + }; }; #pragma pack() @@ -20,21 +24,15 @@ struct RWLock Array rlock_list; // read lock list u32 m_protocol; // TODO - u32 m_pshared; // not used - u64 m_key; // not used - s32 m_flags; // not used union { - u64 m_name_data; // not used + u64 m_name_u64; char m_name[8]; }; - RWLock(u32 protocol, u32 pshared, u64 key, s32 flags, u64 name) + RWLock(u32 protocol, u64 name) : m_protocol(protocol) - , m_pshared(pshared) - , m_key(key) - , m_flags(flags) - , m_name_data(name) + , m_name_u64(name) , wlock_thread(0) { } diff --git a/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp b/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp index cf2e6e4a29..d816cffbe9 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp @@ -194,13 +194,12 @@ int sys_spu_thread_get_exit_status(u32 id, mem32_t status) return CELL_ESRCH; } - if (!(*(SPUThread*)thr).SPU.Out_MBox.GetCount() || !thr->IsStopped()) + u32 res; + if (!(*(SPUThread*)thr).SPU.Out_MBox.Pop(res) || !thr->IsStopped()) { return CELL_ESTAT; } - u32 res; - (*(SPUThread*)thr).SPU.Out_MBox.PopUncond(res); status = res; return CELL_OK; } diff --git a/rpcs3/Emu/event.h b/rpcs3/Emu/event.h index 4cf5472f6b..516ea06ed7 100644 --- a/rpcs3/Emu/event.h +++ b/rpcs3/Emu/event.h @@ -1,18 +1,28 @@ #pragma once +enum EventQueueType +{ + SYS_PPU_QUEUE = 1, + SYS_SPU_QUEUE = 2, +}; + struct sys_event_queue_attr { - u32 attr_protocol; - int type; - char name[8]; + be_t protocol; // SYS_SYNC_PRIORITY or SYS_SYNC_FIFO + be_t type; + union + { + char name[8]; + u64 name_u64; + }; }; struct sys_event_data { - u64 source; - u64 data1; - u64 data2; - u64 data3; + be_t source; + be_t data1; + be_t data2; + be_t data3; }; struct EventQueue; @@ -34,6 +44,19 @@ struct EventQueue EventPort* ports[127]; int size; int pos; - int type; - char name[8]; + + u32 m_protocol; + int m_type; + u64 m_name; + u64 m_key; + + EventQueue(u32 protocol, int type, u64 name, u64 key, int size) + : m_type(type) + , m_protocol(protocol) + , m_name(name) + , m_key(key) + , size(size) + , pos(0) + { + } }; \ No newline at end of file