diff --git a/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp b/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp index 8615526a68..a9173350a1 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +#include "Utilities/Log.h" #include "Emu/System.h" #include "Emu/Memory/Memory.h" #include "Emu/ARMv7/PSVFuncList.h" diff --git a/rpcs3/Emu/ARMv7/PSVFuncList.cpp b/rpcs3/Emu/ARMv7/PSVFuncList.cpp index d9901d8aca..d1d3d2b1a6 100644 --- a/rpcs3/Emu/ARMv7/PSVFuncList.cpp +++ b/rpcs3/Emu/ARMv7/PSVFuncList.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +#include "Utilities/Log.h" #include "Emu/System.h" #include "PSVFuncList.h" diff --git a/rpcs3/Emu/IdManager.h b/rpcs3/Emu/IdManager.h index f335e20631..ef3c78aacd 100644 --- a/rpcs3/Emu/IdManager.h +++ b/rpcs3/Emu/IdManager.h @@ -225,17 +225,34 @@ public: return true; } - //u32 GetTypeCount(IDType type) - //{ - // if (type < TYPE_OTHER) { - // return (u32)m_types[type].size(); - // } - // return 1; - //} + u32 GetTypeCount(IDType type) + { + std::lock_guard lock(m_mtx_main); - //const std::set& GetTypeIDs(IDType type) - //{ - // assert(type < TYPE_OTHER); - // return m_types[type]; - //} + if (type < TYPE_OTHER) + { + return (u32)m_types[type].size(); + } + else + { + assert(!"Invalid ID type"); + return 0; + } + } + + std::set GetTypeIDs(IDType type) + { + // you cannot simply return reference to existing set + std::lock_guard lock(m_mtx_main); + + if (type < TYPE_OTHER) + { + return m_types[type]; + } + else + { + assert(!"Invalid ID type"); + return{}; + } + } }; diff --git a/rpcs3/Emu/SysCalls/SyncPrimitivesManager.cpp b/rpcs3/Emu/SysCalls/SyncPrimitivesManager.cpp new file mode 100644 index 0000000000..3639b94ad6 --- /dev/null +++ b/rpcs3/Emu/SysCalls/SyncPrimitivesManager.cpp @@ -0,0 +1,75 @@ +#include "stdafx.h" +#include "Utilities/Log.h" +#include "Emu/System.h" +#include "Emu/IdManager.h" +#include "Emu/Memory/atomic_type.h" +#include "Utilities/SQueue.h" + +#include "lv2/sleep_queue_type.h" +#include "lv2/sys_lwmutex.h" +#include "lv2/sys_lwcond.h" +#include "lv2/sys_mutex.h" +#include "lv2/sys_cond.h" +#include "lv2/sys_semaphore.h" +#include "SyncPrimitivesManager.h" + +SemaphoreAttributes SyncPrimManager::GetSemaphoreData(u32 id) +{ + std::shared_ptr sem; + if (!Emu.GetIdManager().GetIDData(id, sem)) + { + return{}; + } + + return{ std::string((const char*)&sem->name, 8), sem->value, sem->max }; +} + +LwMutexAttributes SyncPrimManager::GetLwMutexData(u32 id) +{ + std::shared_ptr sq; + if (!Emu.GetIdManager().GetIDData(id, sq)) + { + return{}; + } + + return{ std::string((const char*)&sq->name, 8) }; +} + +std::string SyncPrimManager::GetSyncPrimName(u32 id, IDType type) +{ + switch (type) + { + case TYPE_LWCOND: + { + std::shared_ptr lw; + if (Emu.GetIdManager().GetIDData(id, lw)) + { + return std::string((const char*)&lw->queue.name, 8); + } + break; + } + + case TYPE_MUTEX: + { + std::shared_ptr mutex; + if (Emu.GetIdManager().GetIDData(id, mutex)) + { + return std::string((const char*)&mutex->queue.name, 8); + } + break; + } + + case TYPE_COND: + { + std::shared_ptr cond; + if (Emu.GetIdManager().GetIDData(id, cond)) + { + return std::string((const char*)&cond->queue.name, 8); + } + break; + } + } + + LOG_ERROR(GENERAL, "SyncPrimManager::GetSyncPrimName(id=%d, type=%d) failed", id, type); + return "NOT_FOUND"; +} diff --git a/rpcs3/Emu/SysCalls/SyncPrimitivesManager.h b/rpcs3/Emu/SysCalls/SyncPrimitivesManager.h index 97110e2a50..34f20c05f8 100644 --- a/rpcs3/Emu/SysCalls/SyncPrimitivesManager.h +++ b/rpcs3/Emu/SysCalls/SyncPrimitivesManager.h @@ -1,119 +1,27 @@ #pragma once -#include -#include "Emu/System.h" -#include "Emu/IdManager.h" -#include "Utilities/Log.h" - struct SemaphoreAttributes { std::string name; - u32 count; - u32 max_count; - - SemaphoreAttributes() {} - SemaphoreAttributes(const std::string& _name, u32 _count, u32 _max_count) : name(_name), count(_count), max_count(_max_count) {} + s32 count; + s32 max_count; }; struct LwMutexAttributes { std::string name; - u32 owner_id; - std::string status; // TODO: check status? - - LwMutexAttributes() {} - LwMutexAttributes(const std::string& _name, u32 _owner_id, std::string _status = "INITIALIZED") - : name(_name), owner_id(_owner_id), status(_status) {} }; class SyncPrimManager { private: - std::map m_cond_name; - std::map m_mutex_name; - std::map m_lw_cond_name; - std::map m_lw_mutex_attr; - std::map m_semaph_attr; public: - - // semaphores - void AddSemaphoreData(const u32 id, const std::string& name, const u32 count, const u32 max_count) - { - m_semaph_attr[id] = *(new SemaphoreAttributes(name, count, max_count)); - } - - void EraseSemaphoreData(const u32 id) - { - m_semaph_attr.erase(id); - } - - SemaphoreAttributes& GetSemaphoreData(const u32 id) - { - return m_semaph_attr[id]; - } - - // lw_mutexes - void AddLwMutexData(const u32 id, const std::string& name, const u32 owner_id) - { - m_lw_mutex_attr[id] = *(new LwMutexAttributes(name, owner_id)); - } - - void EraseLwMutexData(const u32 id) - { - m_lw_mutex_attr.erase(id); - } - - LwMutexAttributes& GetLwMutexData(const u32 id) - { - return m_lw_mutex_attr[id]; - } - - // lw_conditions, mutexes, conditions - void AddSyncPrimData(const IDType type, const u32 id, const std::string& name) - { - switch (type) - { - case TYPE_LWCOND: m_lw_cond_name[id] = name; break; - case TYPE_MUTEX: m_mutex_name[id] = name; break; - case TYPE_COND: m_cond_name[id] = name; break; - - default: LOG_ERROR(GENERAL, "Unknown IDType = %d", type); - } - } - - void EraseSyncPrimData(const IDType type, const u32 id) - { - switch (type) - { - case TYPE_LWCOND: m_lw_cond_name.erase(id); break; - case TYPE_MUTEX: m_mutex_name.erase(id); break; - case TYPE_COND: m_cond_name.erase(id); break; - - default: LOG_ERROR(GENERAL, "Unknown IDType = %d", type); - } - } - - const std::string& GetSyncPrimName(const IDType type, const u32 id) - { - static const std::string empty = ""; - - switch (type) - { - case TYPE_LWCOND: return m_lw_cond_name[id]; - case TYPE_MUTEX: return m_mutex_name[id]; - case TYPE_COND: return m_cond_name[id]; - - default: LOG_ERROR(GENERAL, "Unknown IDType = %d", type); return empty; - } - } + SemaphoreAttributes GetSemaphoreData(u32 id); + LwMutexAttributes GetLwMutexData(u32 id); + std::string GetSyncPrimName(u32 id, IDType type); void Close() { - m_cond_name.clear(); - m_mutex_name.clear(); - m_lw_cond_name.clear(); - m_lw_mutex_attr.clear(); - m_semaph_attr.clear(); } }; \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/lv2/sleep_queue_type.cpp b/rpcs3/Emu/SysCalls/lv2/sleep_queue_type.cpp index 6aaef287dc..07b1d8fa84 100644 --- a/rpcs3/Emu/SysCalls/lv2/sleep_queue_type.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sleep_queue_type.cpp @@ -2,14 +2,25 @@ #include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" +#include "Emu/IdManager.h" #include "Emu/Memory/atomic_type.h" #include "Emu/CPU/CPUThreadManager.h" #include "Emu/Cell/PPUThread.h" #include "sleep_queue_type.h" +sleep_queue_t::~sleep_queue_t() +{ + for (auto& tid : m_list) + { + LOG_NOTICE(HLE, "~sleep_queue_t(): thread %d", tid); + } +} + void sleep_queue_t::push(u32 tid, u32 protocol) { + assert(tid); + switch (protocol & SYS_SYNC_ATTR_PROTOCOL_MASK) { case SYS_SYNC_FIFO: @@ -17,7 +28,15 @@ void sleep_queue_t::push(u32 tid, u32 protocol) { std::lock_guard lock(m_mutex); - list.push_back(tid); + for (auto& v : m_list) + { + if (v == tid) + { + assert(!"sleep_queue_t::push() failed (duplication)"); + } + } + + m_list.push_back(tid); return; } case SYS_SYNC_RETRY: @@ -38,18 +57,20 @@ u32 sleep_queue_t::pop(u32 protocol) { std::lock_guard lock(m_mutex); - while (true) + if (m_list.size()) { - if (list.size()) + const u32 res = m_list[0]; + if (!Emu.GetIdManager().CheckID(res)) { - u32 res = list[0]; - list.erase(list.begin()); - if (res && Emu.GetIdManager().CheckID(res)) - // check thread - { - return res; - } + LOG_ERROR(HLE, "sleep_queue_t::pop(SYS_SYNC_FIFO): invalid thread (%d)", res); + Emu.Pause(); } + + m_list.erase(m_list.begin()); + return res; + } + else + { return 0; } } @@ -57,42 +78,33 @@ u32 sleep_queue_t::pop(u32 protocol) { std::lock_guard lock(m_mutex); - while (true) + u64 highest_prio = ~0ull; + u64 sel = ~0ull; + for (auto& v : m_list) { - if (list.size()) + if (std::shared_ptr t = Emu.GetCPU().GetThread(v)) { - u64 highest_prio = ~0ull; - u32 sel = 0; - for (u32 i = 0; i < list.size(); i++) + const u64 prio = t->GetPrio(); + if (prio < highest_prio) { - if (std::shared_ptr t = Emu.GetCPU().GetThread(list[i])) - { - u64 prio = t->GetPrio(); - if (prio < highest_prio) - { - highest_prio = prio; - sel = i; - } - } - else - { - list[i] = 0; - sel = i; - break; - } - } - u32 res = list[sel]; - list.erase(list.begin() + sel); - /* if (Emu.GetIdManager().CheckID(res)) */ - if (res) - // check thread - { - return res; + highest_prio = prio; + sel = &v - m_list.data(); } } - - return 0; + else + { + LOG_ERROR(HLE, "sleep_queue_t::pop(SYS_SYNC_PRIORITY): invalid thread (%d)", v); + Emu.Pause(); + } } + + if (~sel) + { + const u32 res = m_list[sel]; + m_list.erase(m_list.begin() + sel); + return res; + } + // fallthrough } case SYS_SYNC_RETRY: { @@ -107,13 +119,15 @@ u32 sleep_queue_t::pop(u32 protocol) bool sleep_queue_t::invalidate(u32 tid) { + assert(tid); + std::lock_guard lock(m_mutex); - if (tid) for (u32 i = 0; i < list.size(); i++) + for (auto& v : m_list) { - if (list[i] == tid) + if (v == tid) { - list.erase(list.begin() + i); + m_list.erase(m_list.begin() + (&v - m_list.data())); return true; } } @@ -125,27 +139,5 @@ u32 sleep_queue_t::count() { std::lock_guard lock(m_mutex); - u32 result = 0; - for (u32 i = 0; i < list.size(); i++) - { - if (list[i]) result++; - } - return result; -} - -bool sleep_queue_t::finalize() -{ - if (!m_mutex.try_lock()) return false; - - for (u32 i = 0; i < list.size(); i++) - { - if (list[i]) - { - m_mutex.unlock(); - return false; - } - } - - m_mutex.unlock(); - return true; + return (u32)m_list.size(); } diff --git a/rpcs3/Emu/SysCalls/lv2/sleep_queue_type.h b/rpcs3/Emu/SysCalls/lv2/sleep_queue_type.h index 4782b56671..a05c818ccd 100644 --- a/rpcs3/Emu/SysCalls/lv2/sleep_queue_type.h +++ b/rpcs3/Emu/SysCalls/lv2/sleep_queue_type.h @@ -26,20 +26,23 @@ enum SYS_SYNC_ATTR_RECURSIVE_MASK = 0xF0, //??? }; -struct sleep_queue_t +class sleep_queue_t { - std::vector list; + std::vector m_list; std::mutex m_mutex; - u64 m_name; + +public: + const u64 name; sleep_queue_t(u64 name = 0) - : m_name(name) + : name(name) { } + ~sleep_queue_t(); + void push(u32 tid, u32 protocol); u32 pop(u32 protocol); bool invalidate(u32 tid); u32 count(); - bool finalize(); }; diff --git a/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp b/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp index 7c28ea29a8..eb1ec21cdc 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp @@ -38,7 +38,6 @@ s32 sys_cond_create(vm::ptr cond_id, u32 mutex_id, vm::ptrcond_count++; sys_cond.Warning("*** condition created [%s] (mutex_id=%d): id = %d", std::string(attr->name, 8).c_str(), mutex_id, id); - Emu.GetSyncPrimManager().AddSyncPrimData(TYPE_COND, id, std::string(attr->name, 8)); return CELL_OK; } @@ -55,14 +54,13 @@ s32 sys_cond_destroy(u32 cond_id) return CELL_ESRCH; } - if (!cond->queue.finalize()) + if (cond->queue.count()) // TODO: safely make object unusable { return CELL_EBUSY; } cond->mutex->cond_count--; Emu.GetIdManager().RemoveID(cond_id); - Emu.GetSyncPrimManager().EraseSyncPrimData(TYPE_COND, cond_id); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_event.cpp b/rpcs3/Emu/SysCalls/lv2/sys_event.cpp index 065e2f1da6..16b0b9cc9e 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_event.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_event.cpp @@ -21,10 +21,9 @@ u32 event_queue_create(u32 protocol, s32 type, u64 name_u64, u64 event_queue_key return 0; } - std::string name((const char*)&name_u64, 8); u32 id = sys_event.GetNewId(eq, TYPE_EVENT_QUEUE); sys_event.Warning("*** event_queue created [%s] (protocol=0x%x, type=0x%x, key=0x%llx, size=0x%x): id = %d", - name.c_str(), protocol, type, event_queue_key, size, id); + std::string((const char*)&name_u64, 8).c_str(), protocol, type, event_queue_key, size, id); return id; } @@ -83,28 +82,27 @@ s32 sys_event_queue_destroy(u32 equeue_id, int mode) return CELL_EINVAL; } - u32 tid = GetCurrentPPUThread().GetId(); - - eq->sq.m_mutex.lock(); + //u32 tid = GetCurrentPPUThread().GetId(); + //eq->sq.m_mutex.lock(); //eq->owner.lock(tid); // check if some threads are waiting for an event - if (!mode && eq->sq.list.size()) - { - //eq->owner.unlock(tid); - eq->sq.m_mutex.unlock(); - return CELL_EBUSY; - } + //if (!mode && eq->sq.list.size()) + //{ + // eq->owner.unlock(tid); + // eq->sq.m_mutex.unlock(); + // return CELL_EBUSY; + //} //eq->owner.unlock(tid, ~0); - eq->sq.m_mutex.unlock(); - while (eq->sq.list.size()) - { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack - if (Emu.IsStopped()) - { - sys_event.Warning("sys_event_queue_destroy(equeue=%d) aborted", equeue_id); - break; - } - } + //eq->sq.m_mutex.unlock(); + //while (eq->sq.list.size()) + //{ + // std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + // if (Emu.IsStopped()) + // { + // sys_event.Warning("sys_event_queue_destroy(equeue=%d) aborted", equeue_id); + // break; + // } + //} Emu.GetEventManager().UnregisterKey(eq->key); eq->ports.clear(); @@ -135,20 +133,19 @@ s32 sys_event_queue_tryreceive(u32 equeue_id, vm::ptr event_arra return CELL_OK; } - u32 tid = GetCurrentPPUThread().GetId(); - - eq->sq.m_mutex.lock(); + //u32 tid = GetCurrentPPUThread().GetId(); + //eq->sq.m_mutex.lock(); //eq->owner.lock(tid); - if (eq->sq.list.size()) - { - *number = 0; - //eq->owner.unlock(tid); - eq->sq.m_mutex.unlock(); - return CELL_OK; - } + //if (eq->sq.list.size()) + //{ + // *number = 0; + // eq->owner.unlock(tid); + // eq->sq.m_mutex.unlock(); + // return CELL_OK; + //} *number = eq->events.pop_all(event_array.get_ptr(), size); //eq->owner.unlock(tid); - eq->sq.m_mutex.unlock(); + //eq->sq.m_mutex.unlock(); return CELL_OK; } @@ -251,7 +248,7 @@ u32 event_port_create(u64 name) std::shared_ptr eport(new EventPort()); u32 id = sys_event.GetNewId(eport, TYPE_EVENT_PORT); eport->name = name ? name : ((u64)process_getpid() << 32) | (u64)id; - sys_event.Warning("*** sys_event_port created: id = %d", id); + sys_event.Warning("*** sys_event_port created: id = %d, name=0x%llx", id, eport->name); return id; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp b/rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp index 66f74ff492..338716cbe9 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp @@ -5,6 +5,7 @@ #include "Emu/Memory/atomic_type.h" #include "Utilities/SQueue.h" +#include "Emu/CPU/CPUThreadManager.h" #include "Emu/Cell/PPUThread.h" #include "sleep_queue_type.h" #include "sys_event_flag.h" @@ -13,9 +14,8 @@ SysCallBase sys_event_flag("sys_event_flag"); u32 EventFlag::check() { - sleep_queue_t sq; // TODO: implement without sleep queue - u32 target = 0; + u64 highest_prio = ~0ull; const u64 flag_set = flags.read_sync(); for (u32 i = 0; i < waiters.size(); i++) @@ -28,13 +28,25 @@ u32 EventFlag::check() target = waiters[i].tid; break; } - sq.list.push_back(waiters[i].tid); + else if (protocol == SYS_SYNC_PRIORITY) + { + if (std::shared_ptr t = Emu.GetCPU().GetThread(waiters[i].tid)) + { + const u64 prio = t->GetPrio(); + if (prio < highest_prio) + { + highest_prio = prio; + target = waiters[i].tid; + } + } + else + { + assert(!"EventFlag::check(): waiter not found"); + } + } } } - if (protocol == SYS_SYNC_PRIORITY) - target = sq.pop(SYS_SYNC_PRIORITY); - return target; } @@ -74,11 +86,11 @@ s32 sys_event_flag_create(vm::ptr eflag_id, vm::ptr at default: return CELL_EINVAL; } - std::shared_ptr ef(new EventFlag(init, (u32)attr->protocol, (int)attr->type)); + std::shared_ptr ef(new EventFlag(init, (u32)attr->protocol, (s32)attr->type, attr->name_u64)); u32 id = sys_event_flag.GetNewId(ef, TYPE_EVENT_FLAG); *eflag_id = id; sys_event_flag.Warning("*** event_flag created [%s] (protocol=0x%x, type=0x%x): id = %d", - std::string(attr->name, 8).c_str(), (u32)attr->protocol, (int)attr->type, id); + std::string(attr->name, 8).c_str(), (u32)attr->protocol, (s32)attr->type, id); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_event_flag.h b/rpcs3/Emu/SysCalls/lv2/sys_event_flag.h index 277a4c59a8..4c1a0ce719 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_event_flag.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_event_flag.h @@ -17,9 +17,13 @@ struct sys_event_flag_attr be_t protocol; be_t pshared; be_t ipc_key; - be_t flags; - be_t type; - char name[8]; + be_t flags; + be_t type; + union + { + char name[8]; + u64 name_u64; + }; }; struct EventFlagWaiter @@ -35,12 +39,15 @@ struct EventFlag SQueue signal; std::mutex mutex; // protects waiters std::vector waiters; + const u32 protocol; const int type; + const u64 name; - EventFlag(u64 pattern, u32 protocol, int type) + EventFlag(u64 pattern, u32 protocol, int type, u64 name) : protocol(protocol) , type(type) + , name(name) { flags.write_relaxed(pattern); } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_lwcond.cpp b/rpcs3/Emu/SysCalls/lv2/sys_lwcond.cpp index 60de22fef4..40fd63839b 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_lwcond.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_lwcond.cpp @@ -23,13 +23,7 @@ s32 lwcond_create(sys_lwcond_t& lwcond, sys_lwmutex_t& lwmutex, u64 name_u64) lwcond.lwmutex.set(addr); lwcond.lwcond_queue = id; - std::string name((const char*)&name_u64, 8); - - sys_lwcond.Warning("*** lwcond created [%s] (lwmutex_addr=0x%x): id = %d", - name.c_str(), addr, id); - - Emu.GetSyncPrimManager().AddSyncPrimData(TYPE_LWCOND, id, name); - + sys_lwcond.Warning("*** lwcond created [%s] (lwmutex_addr=0x%x): id = %d", std::string((const char*)&name_u64, 8).c_str(), addr, id); return CELL_OK; } @@ -55,13 +49,12 @@ s32 sys_lwcond_destroy(vm::ptr lwcond) return CELL_ESRCH; } - if (!lw->queue.finalize()) + if (lw->queue.count()) // TODO: safely make object unusable { return CELL_EBUSY; } Emu.GetIdManager().RemoveID(id); - Emu.GetSyncPrimManager().EraseSyncPrimData(TYPE_LWCOND, id); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.cpp b/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.cpp index fe74347d36..3159e7c431 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.cpp @@ -25,11 +25,7 @@ s32 lwmutex_create(sys_lwmutex_t& lwmutex, u32 protocol, u32 recursive, u64 name u32 sq_id = sys_lwmutex.GetNewId(sq, TYPE_LWMUTEX); lwmutex.sleep_queue = sq_id; - std::string name((const char*)&name_u64, 8); - sys_lwmutex.Notice("*** lwmutex created [%s] (attribute=0x%x): sq_id = %d", name.c_str(), protocol | recursive, sq_id); - - Emu.GetSyncPrimManager().AddLwMutexData(sq_id, name, 0); - + sys_lwmutex.Notice("*** lwmutex created [%s] (attribute=0x%x): sq_id = %d", std::string((const char*)&name_u64, 8).c_str(), protocol | recursive, sq_id); return CELL_OK; } @@ -65,17 +61,17 @@ s32 sys_lwmutex_destroy(PPUThread& CPU, vm::ptr lwmutex) 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(be_t::make(~0))) + if (s32 res = lwmutex->trylock(be_t::make(~0))) { - case CELL_OK: - lwmutex->all_info() = 0; - lwmutex->attribute = 0xDEADBEEF; - lwmutex->sleep_queue = 0; - Emu.GetIdManager().RemoveID(sq_id); - Emu.GetSyncPrimManager().EraseLwMutexData(sq_id); - default: return res; + return res; } + + // try to make it unable to lock + lwmutex->all_info() = 0; + lwmutex->attribute = 0xDEADBEEF; + lwmutex->sleep_queue = 0; + Emu.GetIdManager().RemoveID(sq_id); + return CELL_OK; } s32 sys_lwmutex_lock(PPUThread& CPU, vm::ptr lwmutex, u64 timeout) diff --git a/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp b/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp index ff907699fb..e13b59888b 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp @@ -19,17 +19,10 @@ Mutex::~Mutex() sys_mutex.Notice("Mutex(%d) was owned by thread %d (recursive=%d)", id, tid, recursive_count.load()); } - if (!queue.m_mutex.try_lock()) return; - - for (u32 i = 0; i < queue.list.size(); i++) + if (u32 count = queue.count()) { - if (u32 owner = queue.list[i]) - { - sys_mutex.Notice("Mutex(%d) was waited by thread %d", id, owner); - } + sys_mutex.Notice("Mutex(%d) was waited by %d threads", id, count); } - - queue.m_mutex.unlock(); } s32 sys_mutex_create(PPUThread& CPU, vm::ptr mutex_id, vm::ptr attr) @@ -68,9 +61,7 @@ s32 sys_mutex_create(PPUThread& CPU, vm::ptr mutex_id, vm::ptrname, 8).c_str(), (u32) attr->protocol, (is_recursive ? "true" : "false"), id); - Emu.GetSyncPrimManager().AddSyncPrimData(TYPE_MUTEX, id, std::string(attr->name, 8)); // TODO: unlock mutex when owner thread does exit - return CELL_OK; } @@ -98,7 +89,7 @@ s32 sys_mutex_destroy(PPUThread& CPU, u32 mutex_id) return CELL_EBUSY; } - if (!mutex->queue.finalize()) + if (mutex->queue.count()) // TODO: safely make object unusable { if (!mutex->owner.compare_and_swap_test(tid, 0)) { @@ -112,7 +103,6 @@ s32 sys_mutex_destroy(PPUThread& CPU, u32 mutex_id) assert(!"sys_mutex_destroy() failed"); } Emu.GetIdManager().RemoveID(mutex_id); - Emu.GetSyncPrimManager().EraseSyncPrimData(TYPE_MUTEX, mutex_id); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_process.cpp b/rpcs3/Emu/SysCalls/lv2/sys_process.cpp index 749647be31..e42d34cf1a 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_process.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_process.cpp @@ -201,26 +201,26 @@ s32 sys_process_get_number_of_object(u32 object, vm::ptr nump) switch(object) { - //case SYS_MEM_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_MEM); break; - //case SYS_MUTEX_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_MUTEX); break; - //case SYS_COND_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_COND); break; - //case SYS_RWLOCK_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_RWLOCK); break; - //case SYS_INTR_TAG_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_INTR_TAG); break; - //case SYS_INTR_SERVICE_HANDLE_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_INTR_SERVICE_HANDLE); break; - //case SYS_EVENT_QUEUE_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_EVENT_QUEUE); break; - //case SYS_EVENT_PORT_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_EVENT_PORT); break; - //case SYS_TRACE_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_TRACE); break; - //case SYS_SPUIMAGE_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_SPUIMAGE); break; - //case SYS_PRX_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_PRX); break; - //case SYS_SPUPORT_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_SPUPORT); break; - //case SYS_LWMUTEX_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_LWMUTEX); break; - //case SYS_TIMER_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_TIMER); break; - //case SYS_SEMAPHORE_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_SEMAPHORE); break; - //case SYS_LWCOND_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_LWCOND); break; - //case SYS_EVENT_FLAG_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_EVENT_FLAG); break; - //case SYS_FS_FD_OBJECT: - // *nump = Emu.GetIdManager().GetTypeCount(TYPE_FS_FILE) + Emu.GetIdManager().GetTypeCount(TYPE_FS_DIR); - // break; + case SYS_MEM_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_MEM); break; + case SYS_MUTEX_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_MUTEX); break; + case SYS_COND_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_COND); break; + case SYS_RWLOCK_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_RWLOCK); break; + case SYS_INTR_TAG_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_INTR_TAG); break; + case SYS_INTR_SERVICE_HANDLE_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_INTR_SERVICE_HANDLE); break; + case SYS_EVENT_QUEUE_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_EVENT_QUEUE); break; + case SYS_EVENT_PORT_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_EVENT_PORT); break; + case SYS_TRACE_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_TRACE); break; + case SYS_SPUIMAGE_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_SPUIMAGE); break; + case SYS_PRX_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_PRX); break; + case SYS_SPUPORT_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_SPUPORT); break; + case SYS_LWMUTEX_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_LWMUTEX); break; + case SYS_TIMER_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_TIMER); break; + case SYS_SEMAPHORE_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_SEMAPHORE); break; + case SYS_LWCOND_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_LWCOND); break; + case SYS_EVENT_FLAG_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_EVENT_FLAG); break; + case SYS_FS_FD_OBJECT: + *nump = Emu.GetIdManager().GetTypeCount(TYPE_FS_FILE) + Emu.GetIdManager().GetTypeCount(TYPE_FS_DIR); + break; default: return CELL_EINVAL; @@ -239,30 +239,30 @@ s32 sys_process_get_id(u32 object, vm::ptr buffer, u32 size, vm::ptr s #define ADD_OBJECTS(type) { \ u32 i=0; \ - const auto& objects = Emu.GetIdManager().GetTypeIDs(type); \ + const auto objects = Emu.GetIdManager().GetTypeIDs(type); \ for(auto id=objects.begin(); i sem(new Semaphore(initial_count, max_count, protocol, name_u64)); - const std::string name((const char*)&name_u64, 8); const u32 id = sys_semaphore.GetNewId(sem, TYPE_SEMAPHORE); - sys_semaphore.Notice("*** semaphore created [%s] (protocol=0x%x): id = %d", name.c_str(), protocol, id); - Emu.GetSyncPrimManager().AddSemaphoreData(id, name, initial_count, max_count); + sys_semaphore.Notice("*** semaphore created [%s] (protocol=0x%x): id = %d", std::string((const char*)&name_u64, 8).c_str(), protocol, id); return id; } @@ -76,13 +74,12 @@ s32 sys_semaphore_destroy(u32 sem_id) return CELL_ESRCH; } - if (!sem->queue.finalize()) + if (sem->queue.count()) // TODO: safely make object unusable { return CELL_EBUSY; } Emu.GetIdManager().RemoveID(sem_id); - Emu.GetSyncPrimManager().EraseSemaphoreData(sem_id); return CELL_OK; } diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index ab9cd94ec0..9c01efad0c 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -23,6 +23,7 @@ #include "Emu/RSX/GSManager.h" #include "Emu/Audio/AudioManager.h" #include "Emu/FS/VFS.h" +#include "Emu/SysCalls/SyncPrimitivesManager.h" #include "Loader/PSF.h" diff --git a/rpcs3/Emu/System.h b/rpcs3/Emu/System.h index 06046cc1ce..7b8689bc5a 100644 --- a/rpcs3/Emu/System.h +++ b/rpcs3/Emu/System.h @@ -1,7 +1,6 @@ #pragma once #include "Loader/Loader.h" -#include "Emu/SysCalls/SyncPrimitivesManager.h" enum Status { diff --git a/rpcs3/Gui/KernelExplorer.cpp b/rpcs3/Gui/KernelExplorer.cpp index c110fa66ff..c29eceee25 100644 --- a/rpcs3/Gui/KernelExplorer.cpp +++ b/rpcs3/Gui/KernelExplorer.cpp @@ -4,9 +4,10 @@ #include "Emu/System.h" #include "Emu/IdManager.h" -#include "KernelExplorer.h" #include "Emu/CPU/CPUThreadManager.h" #include "Emu/CPU/CPUThread.h" +#include "Emu/SysCalls/SyncPrimitivesManager.h" +#include "KernelExplorer.h" KernelExplorer::KernelExplorer(wxWindow* parent) : wxFrame(parent, wxID_ANY, "Kernel Explorer", wxDefaultPosition, wxSize(700, 450)) @@ -53,135 +54,125 @@ void KernelExplorer::Update() // TODO: FileSystem // Semaphores - //count = Emu.GetIdManager().GetTypeCount(TYPE_SEMAPHORE); - //if (count) - //{ - // sprintf(name, "Semaphores (%d)", count); - // const auto& node = m_tree->AppendItem(root, name); - // const auto& objects = Emu.GetIdManager().GetTypeIDs(TYPE_SEMAPHORE); - // for (const auto& id : objects) - // { - // sprintf(name, "Semaphore: ID = 0x%08x '%s', Count = %d, Max Count = %d", id, Emu.GetSyncPrimManager().GetSemaphoreData(id).name.c_str(), - // Emu.GetSyncPrimManager().GetSemaphoreData(id).count, Emu.GetSyncPrimManager().GetSemaphoreData(id).max_count); - // m_tree->AppendItem(node, name); - // } - //} + count = Emu.GetIdManager().GetTypeCount(TYPE_SEMAPHORE); + if (count) + { + sprintf(name, "Semaphores (%d)", count); + const auto& node = m_tree->AppendItem(root, name); + for (const auto& id : Emu.GetIdManager().GetTypeIDs(TYPE_SEMAPHORE)) + { + auto sem = Emu.GetSyncPrimManager().GetSemaphoreData(id); + sprintf(name, "Semaphore: ID = 0x%08x '%s', Count = %d, Max Count = %d", id, sem.name.c_str(), sem.count, sem.max_count); + m_tree->AppendItem(node, name); + } + } // Mutexes - //count = Emu.GetIdManager().GetTypeCount(TYPE_MUTEX); - //if (count) - //{ - // sprintf(name, "Mutexes (%d)", count); - // const auto& node = m_tree->AppendItem(root, name); - // const auto& objects = Emu.GetIdManager().GetTypeIDs(TYPE_MUTEX); - // for (const auto& id : objects) - // { - // sprintf(name, "Mutex: ID = 0x%08x '%s'", id, Emu.GetSyncPrimManager().GetSyncPrimName(TYPE_MUTEX, id).c_str()); - // m_tree->AppendItem(node, name); - // } - //} + count = Emu.GetIdManager().GetTypeCount(TYPE_MUTEX); + if (count) + { + sprintf(name, "Mutexes (%d)", count); + const auto& node = m_tree->AppendItem(root, name); + for (const auto& id : Emu.GetIdManager().GetTypeIDs(TYPE_MUTEX)) + { + sprintf(name, "Mutex: ID = 0x%08x '%s'", id, Emu.GetSyncPrimManager().GetSyncPrimName(id, TYPE_MUTEX).c_str()); + m_tree->AppendItem(node, name); + } + } // Light Weight Mutexes - //count = Emu.GetIdManager().GetTypeCount(TYPE_LWMUTEX); - //if (count) - //{ - // sprintf(name, "Light Weight Mutexes (%d)", count); - // const auto& node = m_tree->AppendItem(root, name); - // const auto& objects = Emu.GetIdManager().GetTypeIDs(TYPE_LWMUTEX); - // for (const auto& id : objects) - // { - // sprintf(name, "LW Mutex: ID = 0x%08x '%s', Owner Thread ID = 0x%08x - %s", id, Emu.GetSyncPrimManager().GetLwMutexData(id).name.c_str(), - // Emu.GetSyncPrimManager().GetLwMutexData(id).owner_id, Emu.GetSyncPrimManager().GetLwMutexData(id).status.c_str()); - // m_tree->AppendItem(node, name); - // } - //} + count = Emu.GetIdManager().GetTypeCount(TYPE_LWMUTEX); + if (count) + { + sprintf(name, "Light Weight Mutexes (%d)", count); + const auto& node = m_tree->AppendItem(root, name); + for (const auto& id : Emu.GetIdManager().GetTypeIDs(TYPE_LWMUTEX)) + { + auto lwm = Emu.GetSyncPrimManager().GetLwMutexData(id); + sprintf(name, "LW Mutex: ID = 0x%08x '%s'", id, lwm.name.c_str()); + m_tree->AppendItem(node, name); + } + } // Condition Variables - //count = Emu.GetIdManager().GetTypeCount(TYPE_COND); - //if (count) - //{ - // sprintf(name, "Condition Variables (%d)", count); - // const auto& node = m_tree->AppendItem(root, name); - // const auto& objects = Emu.GetIdManager().GetTypeIDs(TYPE_COND); - // for (const auto& id : objects) - // { - // sprintf(name, "Condition Variable: ID = 0x%08x '%s'", id, Emu.GetSyncPrimManager().GetSyncPrimName(TYPE_COND, id).c_str()); - // m_tree->AppendItem(node, name); - // } - //} + count = Emu.GetIdManager().GetTypeCount(TYPE_COND); + if (count) + { + sprintf(name, "Condition Variables (%d)", count); + const auto& node = m_tree->AppendItem(root, name); + for (const auto& id : Emu.GetIdManager().GetTypeIDs(TYPE_COND)) + { + sprintf(name, "Condition Variable: ID = 0x%08x '%s'", id, Emu.GetSyncPrimManager().GetSyncPrimName(id, TYPE_COND).c_str()); + m_tree->AppendItem(node, name); + } + } // Light Weight Condition Variables - //count = Emu.GetIdManager().GetTypeCount(TYPE_LWCOND); - //if (count) - //{ - // sprintf(name, "Light Weight Condition Variables (%d)", count); - // const auto& node = m_tree->AppendItem(root, name); - // const auto& objects = Emu.GetIdManager().GetTypeIDs(TYPE_LWCOND); - - // for (const auto& id : objects) - // { - // sprintf(name, "LW Condition Variable: ID = 0x%08x '%s'", id, Emu.GetSyncPrimManager().GetSyncPrimName(TYPE_LWCOND, id).c_str()); - // m_tree->AppendItem(node, name); - // } - //} + count = Emu.GetIdManager().GetTypeCount(TYPE_LWCOND); + if (count) + { + sprintf(name, "Light Weight Condition Variables (%d)", count); + const auto& node = m_tree->AppendItem(root, name); + for (const auto& id : Emu.GetIdManager().GetTypeIDs(TYPE_LWCOND)) + { + sprintf(name, "LW Condition Variable: ID = 0x%08x '%s'", id, Emu.GetSyncPrimManager().GetSyncPrimName(id, TYPE_LWCOND).c_str()); + m_tree->AppendItem(node, name); + } + } // Event Queues - //count = Emu.GetIdManager().GetTypeCount(TYPE_EVENT_QUEUE); - //if (count) - //{ - // sprintf(name, "Event Queues (%d)", count); - // const auto& node = m_tree->AppendItem(root, name); - // const auto& objects = Emu.GetIdManager().GetTypeIDs(TYPE_EVENT_QUEUE); - // for (const auto& id : objects) - // { - // sprintf(name, "Event Queue: ID = 0x%08x", id); - // m_tree->AppendItem(node, name); - // } - //} + count = Emu.GetIdManager().GetTypeCount(TYPE_EVENT_QUEUE); + if (count) + { + sprintf(name, "Event Queues (%d)", count); + const auto& node = m_tree->AppendItem(root, name); + for (const auto& id : Emu.GetIdManager().GetTypeIDs(TYPE_EVENT_QUEUE)) + { + sprintf(name, "Event Queue: ID = 0x%08x", id); + m_tree->AppendItem(node, name); + } + } // Modules - //count = Emu.GetIdManager().GetTypeCount(TYPE_PRX); - //if (count) - //{ - // sprintf(name, "Modules (%d)", count); - // const auto& node = m_tree->AppendItem(root, name); - // const auto& objects = Emu.GetIdManager().GetTypeIDs(TYPE_PRX); - // sprintf(name, "Segment List (%l)", 2 * objects.size()); // TODO: Assuming 2 segments per PRX file is not good - // m_tree->AppendItem(node, name); - // for (const auto& id : objects) - // { - // sprintf(name, "PRX: ID = 0x%08x", id); - // m_tree->AppendItem(node, name); - // } - //} + count = Emu.GetIdManager().GetTypeCount(TYPE_PRX); + if (count) + { + sprintf(name, "Modules (%d)", count); + const auto& node = m_tree->AppendItem(root, name); + //sprintf(name, "Segment List (%l)", 2 * objects.size()); // TODO: Assuming 2 segments per PRX file is not good + //m_tree->AppendItem(node, name); + for (const auto& id : Emu.GetIdManager().GetTypeIDs(TYPE_PRX)) + { + sprintf(name, "PRX: ID = 0x%08x", id); + m_tree->AppendItem(node, name); + } + } // Memory Containers - //count = Emu.GetIdManager().GetTypeCount(TYPE_MEM); - //if (count) - //{ - // sprintf(name, "Memory Containers (%d)", count); - // const auto& node = m_tree->AppendItem(root, name); - // const auto& objects = Emu.GetIdManager().GetTypeIDs(TYPE_MEM); - // for (const auto& id : objects) - // { - // sprintf(name, "Memory Container: ID = 0x%08x", id); - // m_tree->AppendItem(node, name); - // } - //} + count = Emu.GetIdManager().GetTypeCount(TYPE_MEM); + if (count) + { + sprintf(name, "Memory Containers (%d)", count); + const auto& node = m_tree->AppendItem(root, name); + for (const auto& id : Emu.GetIdManager().GetTypeIDs(TYPE_MEM)) + { + sprintf(name, "Memory Container: ID = 0x%08x", id); + m_tree->AppendItem(node, name); + } + } // Event Flags - //count = Emu.GetIdManager().GetTypeCount(TYPE_EVENT_FLAG); - //if (count) - //{ - // sprintf(name, "Event Flags (%d)", count); - // const auto& node = m_tree->AppendItem(root, name); - // const auto& objects = Emu.GetIdManager().GetTypeIDs(TYPE_EVENT_FLAG); - // for (const auto& id : objects) - // { - // sprintf(name, "Event Flag: ID = 0x%08x", id); - // m_tree->AppendItem(node, name); - // } - //} + count = Emu.GetIdManager().GetTypeCount(TYPE_EVENT_FLAG); + if (count) + { + sprintf(name, "Event Flags (%d)", count); + const auto& node = m_tree->AppendItem(root, name); + for (const auto& id : Emu.GetIdManager().GetTypeIDs(TYPE_EVENT_FLAG)) + { + sprintf(name, "Event Flag: ID = 0x%08x", id); + m_tree->AppendItem(node, name); + } + } // PPU / SPU / RawSPU threads { diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index b465f70e76..e5dacacccb 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -236,6 +236,7 @@ + diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index 92eaaf8acc..40cac8b21b 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -653,6 +653,9 @@ Emu\SysCalls\lv2 + + Emu\SysCalls +