From b21fce4d6f8062e0abd4ea9fe762dc940088c8c7 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sun, 29 Jan 2017 19:50:18 +0300 Subject: [PATCH] IdManager improved lv2_obj for kernel objects Simple lookup (vector) Another idm API refactoring --- .clang-format | 2 +- rpcs3/Emu/Cell/Modules/cellAudio.cpp | 4 +- rpcs3/Emu/Cell/Modules/cellDmux.cpp | 2 +- rpcs3/Emu/Cell/Modules/cellJpgDec.h | 2 +- rpcs3/Emu/Cell/Modules/cellVpost.h | 2 +- rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp | 4 +- rpcs3/Emu/Cell/Modules/sys_heap.cpp | 2 +- rpcs3/Emu/Cell/Modules/sys_lwcond_.cpp | 2 +- rpcs3/Emu/Cell/Modules/sys_lwmutex_.cpp | 2 +- rpcs3/Emu/Cell/Modules/sys_mempool.cpp | 2 +- rpcs3/Emu/Cell/Modules/sys_ppu_thread_.cpp | 2 +- rpcs3/Emu/Cell/PPUModule.cpp | 4 +- rpcs3/Emu/Cell/PPUThread.h | 2 +- rpcs3/Emu/Cell/SPUThread.cpp | 6 +- rpcs3/Emu/Cell/SPUThread.h | 16 +- rpcs3/Emu/Cell/lv2/sys_cond.cpp | 18 +- rpcs3/Emu/Cell/lv2/sys_cond.h | 10 +- rpcs3/Emu/Cell/lv2/sys_event.cpp | 48 +- rpcs3/Emu/Cell/lv2/sys_event.h | 18 +- rpcs3/Emu/Cell/lv2/sys_event_flag.cpp | 24 +- rpcs3/Emu/Cell/lv2/sys_event_flag.h | 6 +- rpcs3/Emu/Cell/lv2/sys_fs.h | 6 +- rpcs3/Emu/Cell/lv2/sys_interrupt.cpp | 20 +- rpcs3/Emu/Cell/lv2/sys_interrupt.h | 16 +- rpcs3/Emu/Cell/lv2/sys_lwcond.cpp | 20 +- rpcs3/Emu/Cell/lv2/sys_lwcond.h | 8 +- rpcs3/Emu/Cell/lv2/sys_lwmutex.cpp | 14 +- rpcs3/Emu/Cell/lv2/sys_lwmutex.h | 6 +- rpcs3/Emu/Cell/lv2/sys_mmapper.cpp | 12 +- rpcs3/Emu/Cell/lv2/sys_mmapper.h | 5 +- rpcs3/Emu/Cell/lv2/sys_mutex.cpp | 14 +- rpcs3/Emu/Cell/lv2/sys_mutex.h | 6 +- rpcs3/Emu/Cell/lv2/sys_process.cpp | 70 +-- rpcs3/Emu/Cell/lv2/sys_prx.cpp | 12 +- rpcs3/Emu/Cell/lv2/sys_prx.h | 7 +- rpcs3/Emu/Cell/lv2/sys_rwlock.cpp | 20 +- rpcs3/Emu/Cell/lv2/sys_rwlock.h | 6 +- rpcs3/Emu/Cell/lv2/sys_semaphore.cpp | 14 +- rpcs3/Emu/Cell/lv2/sys_semaphore.h | 6 +- rpcs3/Emu/Cell/lv2/sys_spu.cpp | 42 +- rpcs3/Emu/Cell/lv2/sys_spu.h | 12 +- rpcs3/Emu/Cell/lv2/sys_sync.h | 9 + rpcs3/Emu/Cell/lv2/sys_timer.cpp | 24 +- rpcs3/Emu/Cell/lv2/sys_timer.h | 6 +- rpcs3/Emu/IdManager.cpp | 124 ++--- rpcs3/Emu/IdManager.h | 518 +++++++++++---------- rpcs3/Emu/PSP2/ARMv7Thread.h | 2 +- rpcs3/Emu/PSP2/Modules/sceLibKernel.cpp | 4 +- rpcs3/Emu/PSP2/Modules/sceLibKernel.h | 12 +- rpcs3/Emu/System.cpp | 39 +- rpcs3/Gui/InterpreterDisAsm.cpp | 9 +- rpcs3/Gui/KernelExplorer.cpp | 336 +++++++------ 52 files changed, 812 insertions(+), 765 deletions(-) diff --git a/.clang-format b/.clang-format index 266b7859e8..02a0372579 100644 --- a/.clang-format +++ b/.clang-format @@ -5,7 +5,7 @@ IndentWidth: 1 AccessModifierOffset: -1 PointerAlignment: Left NamespaceIndentation: All -ColumnLimit: 100 +ColumnLimit: 200 BreakBeforeBraces: Allman BreakConstructorInitializersBeforeComma: true BreakBeforeBinaryOperators: false diff --git a/rpcs3/Emu/Cell/Modules/cellAudio.cpp b/rpcs3/Emu/Cell/Modules/cellAudio.cpp index f2aeac0bb4..11aa988bf8 100644 --- a/rpcs3/Emu/Cell/Modules/cellAudio.cpp +++ b/rpcs3/Emu/Cell/Modules/cellAudio.cpp @@ -278,7 +278,7 @@ void audio_config::on_task() for (u64 key : keys) { - if (auto&& queue = lv2_event_queue_t::find(key)) + if (auto&& queue = lv2_event_queue::find(key)) { if (queue->events() < queue->size) queue->push(lv2_lock, 0, 0, 0, 0); // TODO: check arguments @@ -656,7 +656,7 @@ s32 cellAudioCreateNotifyEventQueue(vm::ptr id, vm::ptr key) const u64 key_value = 0x80004d494f323221ull + k; // Create an event queue "bruteforcing" an available key - if (auto&& queue = lv2_event_queue_t::make(SYS_SYNC_FIFO, SYS_PPU_QUEUE, 0, key_value, 32)) + if (auto&& queue = lv2_event_queue::make(SYS_SYNC_FIFO, SYS_PPU_QUEUE, 0, key_value, 32)) { *id = queue->id; *key = key_value; diff --git a/rpcs3/Emu/Cell/Modules/cellDmux.cpp b/rpcs3/Emu/Cell/Modules/cellDmux.cpp index 19402ab681..0d54865fc4 100644 --- a/rpcs3/Emu/Cell/Modules/cellDmux.cpp +++ b/rpcs3/Emu/Cell/Modules/cellDmux.cpp @@ -145,7 +145,7 @@ class ElementaryStream public: static const u32 id_base = 1; static const u32 id_step = 1; - static const u32 id_count = 32767; + static const u32 id_count = 1023; ElementaryStream(Demuxer* dmux, u32 addr, u32 size, u32 fidMajor, u32 fidMinor, u32 sup1, u32 sup2, vm::ptr cbFunc, u32 cbArg, u32 spec); diff --git a/rpcs3/Emu/Cell/Modules/cellJpgDec.h b/rpcs3/Emu/Cell/Modules/cellJpgDec.h index d3ba5f6461..cabffcbd25 100644 --- a/rpcs3/Emu/Cell/Modules/cellJpgDec.h +++ b/rpcs3/Emu/Cell/Modules/cellJpgDec.h @@ -111,7 +111,7 @@ struct CellJpgDecSubHandle { static const u32 id_base = 1; static const u32 id_step = 1; - static const u32 id_count = 32767; + static const u32 id_count = 1023; u32 fd; u64 fileSize; diff --git a/rpcs3/Emu/Cell/Modules/cellVpost.h b/rpcs3/Emu/Cell/Modules/cellVpost.h index 8ca22ffc20..d9c4af52c5 100644 --- a/rpcs3/Emu/Cell/Modules/cellVpost.h +++ b/rpcs3/Emu/Cell/Modules/cellVpost.h @@ -323,7 +323,7 @@ class VpostInstance public: static const u32 id_base = 1; static const u32 id_step = 1; - static const u32 id_count = 32767; + static const u32 id_count = 1023; const bool to_rgba; diff --git a/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp b/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp index f88c1dec79..753d6dd1c1 100644 --- a/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp @@ -20,7 +20,7 @@ struct trophy_context_t { static const u32 id_base = 1; static const u32 id_step = 1; - static const u32 id_count = 32767; + static const u32 id_count = 1023; const u32 id = idm::last_id(); @@ -33,7 +33,7 @@ struct trophy_handle_t { static const u32 id_base = 1; static const u32 id_step = 1; - static const u32 id_count = 32767; + static const u32 id_count = 1023; const u32 id = idm::last_id(); }; diff --git a/rpcs3/Emu/Cell/Modules/sys_heap.cpp b/rpcs3/Emu/Cell/Modules/sys_heap.cpp index 4c09afb300..909b6b576f 100644 --- a/rpcs3/Emu/Cell/Modules/sys_heap.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_heap.cpp @@ -11,7 +11,7 @@ struct HeapInfo { static const u32 id_base = 1; static const u32 id_step = 1; - static const u32 id_count = 32767; + static const u32 id_count = 1023; const std::string name; diff --git a/rpcs3/Emu/Cell/Modules/sys_lwcond_.cpp b/rpcs3/Emu/Cell/Modules/sys_lwcond_.cpp index af60d1bda3..1097ef3176 100644 --- a/rpcs3/Emu/Cell/Modules/sys_lwcond_.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_lwcond_.cpp @@ -13,7 +13,7 @@ s32 sys_lwcond_create(vm::ptr lwcond, vm::ptr lwmut { sysPrxForUser.warning("sys_lwcond_create(lwcond=*0x%x, lwmutex=*0x%x, attr=*0x%x)", lwcond, lwmutex, attr); - lwcond->lwcond_queue = idm::make(reinterpret_cast(attr->name)); + lwcond->lwcond_queue = idm::make(reinterpret_cast(attr->name)); lwcond->lwmutex = lwmutex; return CELL_OK; diff --git a/rpcs3/Emu/Cell/Modules/sys_lwmutex_.cpp b/rpcs3/Emu/Cell/Modules/sys_lwmutex_.cpp index 4fd6cb4f23..77ca387c6d 100644 --- a/rpcs3/Emu/Cell/Modules/sys_lwmutex_.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_lwmutex_.cpp @@ -34,7 +34,7 @@ s32 sys_lwmutex_create(vm::ptr lwmutex, vm::ptrlock_var.store({ lwmutex_free, 0 }); lwmutex->attribute = attr->recursive | attr->protocol; lwmutex->recursive_count = 0; - lwmutex->sleep_queue = idm::make(protocol, reinterpret_cast(attr->name)); + lwmutex->sleep_queue = idm::make(protocol, reinterpret_cast(attr->name)); return CELL_OK; } diff --git a/rpcs3/Emu/Cell/Modules/sys_mempool.cpp b/rpcs3/Emu/Cell/Modules/sys_mempool.cpp index 89c236b4f2..46ff250d65 100644 --- a/rpcs3/Emu/Cell/Modules/sys_mempool.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_mempool.cpp @@ -13,7 +13,7 @@ struct memory_pool_t { static const u32 id_base = 1; static const u32 id_step = 1; - static const u32 id_count = 32767; + static const u32 id_count = 1023; vm::ptr chunk; u64 chunk_size; diff --git a/rpcs3/Emu/Cell/Modules/sys_ppu_thread_.cpp b/rpcs3/Emu/Cell/Modules/sys_ppu_thread_.cpp index 7d59ce3ff5..74883c46fd 100644 --- a/rpcs3/Emu/Cell/Modules/sys_ppu_thread_.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_ppu_thread_.cpp @@ -45,7 +45,7 @@ s32 sys_ppu_thread_create(vm::ptr thread_id, u32 entry, u64 arg, s32 prio, // Dirty hack for sound: confirm the creation of _mxr000 event queue if (threadname && std::memcmp(threadname.get_ptr(), "_cellsurMixerMain", 18) == 0) { - while (!idm::select([](u32, lv2_event_queue_t& eq) + while (!idm::select([](u32, lv2_event_queue& eq) { return eq.name == "_mxr000\0"_u64; })) diff --git a/rpcs3/Emu/Cell/PPUModule.cpp b/rpcs3/Emu/Cell/PPUModule.cpp index 39741318a8..b53a0787b8 100644 --- a/rpcs3/Emu/Cell/PPUModule.cpp +++ b/rpcs3/Emu/Cell/PPUModule.cpp @@ -733,7 +733,7 @@ static void ppu_load_imports(const std::shared_ptr& link, u32 } } -std::shared_ptr ppu_load_prx(const ppu_prx_object& elf) +std::shared_ptr ppu_load_prx(const ppu_prx_object& elf) { std::vector> segments; std::vector> sections; @@ -887,7 +887,7 @@ std::shared_ptr ppu_load_prx(const ppu_prx_object& elf) const auto link = fxm::get_always(); // Create new PRX object - auto prx = idm::make_ptr(); + auto prx = idm::make_ptr(); if (!elf.progs.empty() && elf.progs[0].p_paddr) { diff --git a/rpcs3/Emu/Cell/PPUThread.h b/rpcs3/Emu/Cell/PPUThread.h index 32a920ede0..ff88544dd9 100644 --- a/rpcs3/Emu/Cell/PPUThread.h +++ b/rpcs3/Emu/Cell/PPUThread.h @@ -22,7 +22,7 @@ class ppu_thread : public cpu_thread public: static const u32 id_base = 0x01000000; // TODO (used to determine thread type) static const u32 id_step = 1; - static const u32 id_count = 65535; + static const u32 id_count = 2048; virtual std::string get_name() const override; virtual std::string dump() const override; diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index 1af320b8be..596f41aeec 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -867,7 +867,7 @@ bool SPUThread::set_ch_value(u32 ch, u32 value) LOG_TRACE(SPU, "sys_event_flag_set_bit(id=%d, value=0x%x (flag=%d))", data, value, flag); - const auto eflag = idm::get(data); + const auto eflag = idm::get(data); if (!eflag) { @@ -908,7 +908,7 @@ bool SPUThread::set_ch_value(u32 ch, u32 value) LOG_TRACE(SPU, "sys_event_flag_set_bit_impatient(id=%d, value=0x%x (flag=%d))", data, value, flag); - const auto eflag = idm::get(data); + const auto eflag = idm::get(data); if (!eflag) { @@ -1179,7 +1179,7 @@ bool SPUThread::stop_and_signal(u32 code) return ch_in_mbox.set_values(1, CELL_EINVAL), true; } - std::shared_ptr queue; + std::shared_ptr queue; for (auto& v : this->spuq) { diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index b5ff1e10bc..149631b170 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -5,9 +5,9 @@ #include "Emu/Cell/SPUInterpreter.h" #include "MFC.h" -class lv2_event_queue_t; -struct lv2_spu_group_t; -struct lv2_int_tag_t; +class lv2_event_queue; +struct lv2_spu_group; +struct lv2_int_tag; // SPU Channels enum : u32 @@ -343,7 +343,7 @@ struct spu_int_ctrl_t atomic_t mask; atomic_t stat; - std::shared_ptr tag; + std::shared_ptr tag; void set(u64 ints); @@ -503,7 +503,7 @@ protected: public: static const u32 id_base = 0x02000000; // TODO (used to determine thread type) static const u32 id_step = 1; - static const u32 id_count = 65535; + static const u32 id_count = 2048; SPUThread(const std::string& name, u32 index); @@ -544,10 +544,10 @@ public: std::array int_ctrl; // SPU Class 0, 1, 2 Interrupt Management - std::weak_ptr tg; // SPU Thread Group + std::weak_ptr tg; // SPU Thread Group - std::array>, 32> spuq; // Event Queue Keys for SPU Thread - std::weak_ptr spup[64]; // SPU Ports + std::array>, 32> spuq; // Event Queue Keys for SPU Thread + std::weak_ptr spup[64]; // SPU Ports u32 pc = 0; // const u32 index; // SPU index diff --git a/rpcs3/Emu/Cell/lv2/sys_cond.cpp b/rpcs3/Emu/Cell/lv2/sys_cond.cpp index c7078782bf..84386662b5 100644 --- a/rpcs3/Emu/Cell/lv2/sys_cond.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_cond.cpp @@ -16,7 +16,7 @@ logs::channel sys_cond("sys_cond", logs::level::notice); extern u64 get_system_time(); -void lv2_cond_t::notify(lv2_lock_t, cpu_thread* thread) +void lv2_cond::notify(lv2_lock_t, cpu_thread* thread) { if (mutex->owner) { @@ -36,7 +36,7 @@ s32 sys_cond_create(vm::ptr cond_id, u32 mutex_id, vm::ptr(mutex_id); + const auto mutex = idm::get(mutex_id); if (!mutex) { @@ -54,7 +54,7 @@ s32 sys_cond_create(vm::ptr cond_id, u32 mutex_id, vm::ptr(mutex, attr->name_u64); + *cond_id = idm::make(mutex, attr->name_u64); return CELL_OK; } @@ -65,7 +65,7 @@ s32 sys_cond_destroy(u32 cond_id) LV2_LOCK; - const auto cond = idm::get(cond_id); + const auto cond = idm::get(cond_id); if (!cond) { @@ -82,7 +82,7 @@ s32 sys_cond_destroy(u32 cond_id) fmt::throw_exception("Unexpected cond_count" HERE); } - idm::remove(cond_id); + idm::remove(cond_id); return CELL_OK; } @@ -93,7 +93,7 @@ s32 sys_cond_signal(u32 cond_id) LV2_LOCK; - const auto cond = idm::get(cond_id); + const auto cond = idm::get(cond_id); if (!cond) { @@ -116,7 +116,7 @@ s32 sys_cond_signal_all(u32 cond_id) LV2_LOCK; - const auto cond = idm::get(cond_id); + const auto cond = idm::get(cond_id); if (!cond) { @@ -140,7 +140,7 @@ s32 sys_cond_signal_to(u32 cond_id, u32 thread_id) LV2_LOCK; - const auto cond = idm::get(cond_id); + const auto cond = idm::get(cond_id); if (!cond) { @@ -173,7 +173,7 @@ s32 sys_cond_wait(ppu_thread& ppu, u32 cond_id, u64 timeout) LV2_LOCK; - const auto cond = idm::get(cond_id); + const auto cond = idm::get(cond_id); if (!cond) { diff --git a/rpcs3/Emu/Cell/lv2/sys_cond.h b/rpcs3/Emu/Cell/lv2/sys_cond.h index 6712de3ac7..11143292d9 100644 --- a/rpcs3/Emu/Cell/lv2/sys_cond.h +++ b/rpcs3/Emu/Cell/lv2/sys_cond.h @@ -2,7 +2,7 @@ #include "sys_sync.h" -struct lv2_mutex_t; +struct lv2_mutex; struct sys_cond_attribute_t { @@ -17,18 +17,16 @@ struct sys_cond_attribute_t }; }; -struct lv2_cond_t +struct lv2_cond final : lv2_obj { static const u32 id_base = 0x86000000; - static const u32 id_step = 0x100; - static const u32 id_count = 8192; const u64 name; - const std::shared_ptr mutex; // associated mutex + const std::shared_ptr mutex; // associated mutex sleep_queue sq; - lv2_cond_t(const std::shared_ptr& mutex, u64 name) + lv2_cond(const std::shared_ptr& mutex, u64 name) : mutex(mutex) , name(name) { diff --git a/rpcs3/Emu/Cell/lv2/sys_event.cpp b/rpcs3/Emu/Cell/lv2/sys_event.cpp index 15200e0f34..e4f3fd8788 100644 --- a/rpcs3/Emu/Cell/lv2/sys_event.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_event.cpp @@ -14,17 +14,17 @@ namespace vm { using namespace ps3; } logs::channel sys_event("sys_event", logs::level::notice); -template<> DECLARE(ipc_manager::g_ipc) {}; +template<> DECLARE(ipc_manager::g_ipc) {}; extern u64 get_system_time(); -std::shared_ptr lv2_event_queue_t::make(u32 protocol, s32 type, u64 name, u64 ipc_key, s32 size) +std::shared_ptr lv2_event_queue::make(u32 protocol, s32 type, u64 name, u64 ipc_key, s32 size) { - std::shared_ptr result; + std::shared_ptr result; - auto make_expr = [&]() -> const std::shared_ptr& + auto make_expr = [&]() -> const std::shared_ptr& { - result = idm::make_ptr(protocol, type, name, ipc_key, size); + result = idm::make_ptr(protocol, type, name, ipc_key, size); return result; }; @@ -36,7 +36,7 @@ std::shared_ptr lv2_event_queue_t::make(u32 protocol, s32 typ } // IPC queue - if (ipc_manager::add(ipc_key, make_expr)) + if (ipc_manager::add(ipc_key, make_expr)) { return result; } @@ -44,7 +44,7 @@ std::shared_ptr lv2_event_queue_t::make(u32 protocol, s32 typ return nullptr; } -std::shared_ptr lv2_event_queue_t::find(u64 ipc_key) +std::shared_ptr lv2_event_queue::find(u64 ipc_key) { if (ipc_key == SYS_EVENT_QUEUE_LOCAL) { @@ -52,10 +52,10 @@ std::shared_ptr lv2_event_queue_t::find(u64 ipc_key) return{}; } - return ipc_manager::get(ipc_key); + return ipc_manager::get(ipc_key); } -lv2_event_queue_t::lv2_event_queue_t(u32 protocol, s32 type, u64 name, u64 ipc_key, s32 size) +lv2_event_queue::lv2_event_queue(u32 protocol, s32 type, u64 name, u64 ipc_key, s32 size) : protocol(protocol) , type(type) , name(name) @@ -65,7 +65,7 @@ lv2_event_queue_t::lv2_event_queue_t(u32 protocol, s32 type, u64 name, u64 ipc_k { } -void lv2_event_queue_t::push(lv2_lock_t, u64 source, u64 data1, u64 data2, u64 data3) +void lv2_event_queue::push(lv2_lock_t, u64 source, u64 data1, u64 data2, u64 data3) { verify(HERE), m_sq.empty() || m_events.empty(); @@ -105,7 +105,7 @@ void lv2_event_queue_t::push(lv2_lock_t, u64 source, u64 data1, u64 data2, u64 d return m_sq.pop_front(); } -lv2_event_queue_t::event_type lv2_event_queue_t::pop(lv2_lock_t) +lv2_event_queue::event_type lv2_event_queue::pop(lv2_lock_t) { verify(HERE), m_events.size(); auto result = m_events.front(); @@ -138,7 +138,7 @@ s32 sys_event_queue_create(vm::ptr equeue_id, vm::ptr(attr->name), event_queue_key, size); + const auto queue = lv2_event_queue::make(protocol, type, reinterpret_cast(attr->name), event_queue_key, size); if (!queue) { @@ -156,7 +156,7 @@ s32 sys_event_queue_destroy(u32 equeue_id, s32 mode) LV2_LOCK; - const auto queue = idm::get(equeue_id); + const auto queue = idm::get(equeue_id); if (!queue) { @@ -174,7 +174,7 @@ s32 sys_event_queue_destroy(u32 equeue_id, s32 mode) } // cleanup - idm::remove(equeue_id); + idm::remove(equeue_id); // signal all threads to return CELL_ECANCELED for (auto& thread : queue->thread_queue(lv2_lock)) @@ -205,7 +205,7 @@ s32 sys_event_queue_tryreceive(u32 equeue_id, vm::ptr event_array, LV2_LOCK; - const auto queue = idm::get(equeue_id); + const auto queue = idm::get(equeue_id); if (!queue) { @@ -244,7 +244,7 @@ s32 sys_event_queue_receive(ppu_thread& ppu, u32 equeue_id, vm::ptr LV2_LOCK; - const auto queue = idm::get(equeue_id); + const auto queue = idm::get(equeue_id); if (!queue) { @@ -305,7 +305,7 @@ s32 sys_event_queue_drain(u32 equeue_id) LV2_LOCK; - const auto queue = idm::get(equeue_id); + const auto queue = idm::get(equeue_id); if (!queue) { @@ -327,7 +327,7 @@ s32 sys_event_port_create(vm::ptr eport_id, s32 port_type, u64 name) return CELL_EINVAL; } - *eport_id = idm::make(port_type, name); + *eport_id = idm::make(port_type, name); return CELL_OK; } @@ -338,7 +338,7 @@ s32 sys_event_port_destroy(u32 eport_id) LV2_LOCK; - const auto port = idm::get(eport_id); + const auto port = idm::get(eport_id); if (!port) { @@ -350,7 +350,7 @@ s32 sys_event_port_destroy(u32 eport_id) return CELL_EISCONN; } - idm::remove(eport_id); + idm::remove(eport_id); return CELL_OK; } @@ -361,8 +361,8 @@ s32 sys_event_port_connect_local(u32 eport_id, u32 equeue_id) LV2_LOCK; - const auto port = idm::get(eport_id); - const auto queue = idm::get(equeue_id); + const auto port = idm::get(eport_id); + const auto queue = idm::get(equeue_id); if (!port || !queue) { @@ -390,7 +390,7 @@ s32 sys_event_port_disconnect(u32 eport_id) LV2_LOCK; - const auto port = idm::get(eport_id); + const auto port = idm::get(eport_id); if (!port) { @@ -417,7 +417,7 @@ s32 sys_event_port_send(u32 eport_id, u64 data1, u64 data2, u64 data3) LV2_LOCK; - const auto port = idm::get(eport_id); + const auto port = idm::get(eport_id); if (!port) { diff --git a/rpcs3/Emu/Cell/lv2/sys_event.h b/rpcs3/Emu/Cell/lv2/sys_event.h index 6acb7551e5..b7bcae64fe 100644 --- a/rpcs3/Emu/Cell/lv2/sys_event.h +++ b/rpcs3/Emu/Cell/lv2/sys_event.h @@ -65,7 +65,7 @@ struct sys_event_t be_t data3; }; -class lv2_event_queue_t final +class lv2_event_queue final : public lv2_obj { // Tuple elements: source, data1, data2, data3 using event_type = std::tuple; @@ -76,14 +76,12 @@ class lv2_event_queue_t final public: static const u32 id_base = 0x8d000000; - static const u32 id_step = 0x100; - static const u32 id_count = 8192; // Try to make an event queue with specified global key - static std::shared_ptr make(u32 protocol, s32 type, u64 name, u64 ipc_key, s32 size); + static std::shared_ptr make(u32 protocol, s32 type, u64 name, u64 ipc_key, s32 size); // Get event queue by its global key - static std::shared_ptr find(u64 ipc_key); + static std::shared_ptr find(u64 ipc_key); const u32 protocol; const s32 type; @@ -92,7 +90,7 @@ public: const s32 size; const u32 id; - lv2_event_queue_t(u32 protocol, s32 type, u64 name, u64 ipc_key, s32 size); + lv2_event_queue(u32 protocol, s32 type, u64 name, u64 ipc_key, s32 size); // Send an event void push(lv2_lock_t, u64 source, u64 data1, u64 data2, u64 data3); @@ -116,18 +114,16 @@ public: auto& thread_queue(lv2_lock_t) { return m_sq; } }; -struct lv2_event_port_t +struct lv2_event_port final : lv2_obj { static const u32 id_base = 0x0e000000; - static const u32 id_step = 0x100; - static const u32 id_count = 8192; const s32 type; // port type, must be SYS_EVENT_PORT_LOCAL const u64 name; // passed as event source (generated from id and process id if not set) - std::weak_ptr queue; // event queue this port is connected to + std::weak_ptr queue; // event queue this port is connected to - lv2_event_port_t(s32 type, u64 name) + lv2_event_port(s32 type, u64 name) : type(type) , name(name) { diff --git a/rpcs3/Emu/Cell/lv2/sys_event_flag.cpp b/rpcs3/Emu/Cell/lv2/sys_event_flag.cpp index a8a451531c..28d5b75494 100644 --- a/rpcs3/Emu/Cell/lv2/sys_event_flag.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_event_flag.cpp @@ -15,7 +15,7 @@ logs::channel sys_event_flag("sys_event_flag", logs::level::notice); extern u64 get_system_time(); -void lv2_event_flag_t::notify_all(lv2_lock_t) +void lv2_event_flag::notify_all(lv2_lock_t) { auto pred = [this](cpu_thread* thread) -> bool { @@ -74,7 +74,7 @@ s32 sys_event_flag_create(vm::ptr id, vm::ptr a return CELL_EINVAL; } - *id = idm::make(init, protocol, type, attr->name_u64); + *id = idm::make(init, protocol, type, attr->name_u64); return CELL_OK; } @@ -85,7 +85,7 @@ s32 sys_event_flag_destroy(u32 id) LV2_LOCK; - const auto eflag = idm::get(id); + const auto eflag = idm::get(id); if (!eflag) { @@ -97,7 +97,7 @@ s32 sys_event_flag_destroy(u32 id) return CELL_EBUSY; } - idm::remove(id); + idm::remove(id); return CELL_OK; } @@ -117,13 +117,13 @@ s32 sys_event_flag_wait(ppu_thread& ppu, u32 id, u64 bitptn, u32 mode, vm::ptr(id); + const auto eflag = idm::get(id); if (!eflag) { @@ -193,13 +193,13 @@ s32 sys_event_flag_trywait(u32 id, u64 bitptn, u32 mode, vm::ptr result) if (result) *result = 0; // This is very annoying. - if (!lv2_event_flag_t::check_mode(mode)) + if (!lv2_event_flag::check_mode(mode)) { sys_event_flag.error("sys_event_flag_trywait(): unknown mode (0x%x)", mode); return CELL_EINVAL; } - const auto eflag = idm::get(id); + const auto eflag = idm::get(id); if (!eflag) { @@ -224,7 +224,7 @@ s32 sys_event_flag_set(u32 id, u64 bitptn) LV2_LOCK; - const auto eflag = idm::get(id); + const auto eflag = idm::get(id); if (!eflag) { @@ -245,7 +245,7 @@ s32 sys_event_flag_clear(u32 id, u64 bitptn) LV2_LOCK; - const auto eflag = idm::get(id); + const auto eflag = idm::get(id); if (!eflag) { @@ -268,7 +268,7 @@ s32 sys_event_flag_cancel(u32 id, vm::ptr num) *num = 0; } - const auto eflag = idm::get(id); + const auto eflag = idm::get(id); if (!eflag) { @@ -312,7 +312,7 @@ s32 sys_event_flag_get(u32 id, vm::ptr flags) return CELL_EFAULT; } - const auto eflag = idm::get(id); + const auto eflag = idm::get(id); if (!eflag) { diff --git a/rpcs3/Emu/Cell/lv2/sys_event_flag.h b/rpcs3/Emu/Cell/lv2/sys_event_flag.h index 4326288e7b..84ed53513c 100644 --- a/rpcs3/Emu/Cell/lv2/sys_event_flag.h +++ b/rpcs3/Emu/Cell/lv2/sys_event_flag.h @@ -29,11 +29,9 @@ struct sys_event_flag_attribute_t }; }; -struct lv2_event_flag_t +struct lv2_event_flag final : lv2_obj { static const u32 id_base = 0x98000000; - static const u32 id_step = 0x100; - static const u32 id_count = 8192; const u32 protocol; const s32 type; @@ -43,7 +41,7 @@ struct lv2_event_flag_t sleep_queue sq; - lv2_event_flag_t(u64 pattern, u32 protocol, s32 type, u64 name) + lv2_event_flag(u64 pattern, u32 protocol, s32 type, u64 name) : pattern(pattern) , protocol(protocol) , type(type) diff --git a/rpcs3/Emu/Cell/lv2/sys_fs.h b/rpcs3/Emu/Cell/lv2/sys_fs.h index 96fc1068f3..84806fe69d 100644 --- a/rpcs3/Emu/Cell/lv2/sys_fs.h +++ b/rpcs3/Emu/Cell/lv2/sys_fs.h @@ -96,6 +96,8 @@ struct lv2_fs_mount_point; struct lv2_fs_object { + using id_type = lv2_fs_object; + static const u32 id_base = 3; static const u32 id_step = 1; static const u32 id_count = 255 - id_base; @@ -114,7 +116,7 @@ struct lv2_fs_object static lv2_fs_mount_point* get_mp(const char* filename); }; -struct lv2_file : lv2_fs_object +struct lv2_file final : lv2_fs_object { const fs::file file; const s32 mode; @@ -135,7 +137,7 @@ struct lv2_file : lv2_fs_object u64 op_write(vm::ps3::cptr buf, u64 size); }; -struct lv2_dir : lv2_fs_object +struct lv2_dir final : lv2_fs_object { const fs::dir dir; diff --git a/rpcs3/Emu/Cell/lv2/sys_interrupt.cpp b/rpcs3/Emu/Cell/lv2/sys_interrupt.cpp index 637c4fbb82..bac4b7fa47 100644 --- a/rpcs3/Emu/Cell/lv2/sys_interrupt.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_interrupt.cpp @@ -12,7 +12,7 @@ namespace vm { using namespace ps3; } logs::channel sys_interrupt("sys_interrupt", logs::level::notice); -lv2_int_serv_t::lv2_int_serv_t(const std::shared_ptr& thread, u64 arg1, u64 arg2) +lv2_int_serv::lv2_int_serv(const std::shared_ptr& thread, u64 arg1, u64 arg2) : thread(thread) , arg1(arg1) , arg2(arg2) @@ -20,7 +20,7 @@ lv2_int_serv_t::lv2_int_serv_t(const std::shared_ptr& thread, u64 ar { } -void lv2_int_serv_t::exec() +void lv2_int_serv::exec() { thread->cmd_list ({ @@ -31,7 +31,7 @@ void lv2_int_serv_t::exec() thread->notify(); } -void lv2_int_serv_t::join(ppu_thread& ppu, lv2_lock_t lv2_lock) +void lv2_int_serv::join(ppu_thread& ppu, lv2_lock_t lv2_lock) { // Enqueue _sys_ppu_thread_exit call thread->cmd_list @@ -52,7 +52,7 @@ void lv2_int_serv_t::join(ppu_thread& ppu, lv2_lock_t lv2_lock) } // Cleanup - idm::remove(id); + idm::remove(id); } s32 sys_interrupt_tag_destroy(u32 intrtag) @@ -61,7 +61,7 @@ s32 sys_interrupt_tag_destroy(u32 intrtag) LV2_LOCK; - const auto tag = idm::get(intrtag); + const auto tag = idm::get(intrtag); if (!tag) { @@ -73,7 +73,7 @@ s32 sys_interrupt_tag_destroy(u32 intrtag) return CELL_EBUSY; } - idm::remove(intrtag); + idm::remove(intrtag); return CELL_OK; } @@ -85,7 +85,7 @@ s32 _sys_interrupt_thread_establish(vm::ptr ih, u32 intrtag, u32 intrthread LV2_LOCK; // Get interrupt tag - const auto tag = idm::get(intrtag); + const auto tag = idm::get(intrtag); if (!tag) { @@ -113,7 +113,7 @@ s32 _sys_interrupt_thread_establish(vm::ptr ih, u32 intrtag, u32 intrthread return CELL_ESTAT; } - tag->handler = idm::make_ptr(it, arg1, arg2); + tag->handler = idm::make_ptr(it, arg1, arg2); it->run(); @@ -128,7 +128,7 @@ s32 _sys_interrupt_thread_disestablish(ppu_thread& ppu, u32 ih, vm::ptr r13 LV2_LOCK; - const auto handler = idm::get(ih); + const auto handler = idm::get(ih); if (!handler) { @@ -160,7 +160,7 @@ void sys_interrupt_thread_eoi(ppu_thread& ppu) // Low-level PPU function example } } -lv2_int_tag_t::lv2_int_tag_t() +lv2_int_tag::lv2_int_tag() : id(idm::last_id()) { } diff --git a/rpcs3/Emu/Cell/lv2/sys_interrupt.h b/rpcs3/Emu/Cell/lv2/sys_interrupt.h index c6f59e1f74..4463b995c1 100644 --- a/rpcs3/Emu/Cell/lv2/sys_interrupt.h +++ b/rpcs3/Emu/Cell/lv2/sys_interrupt.h @@ -4,24 +4,20 @@ class ppu_thread; -struct lv2_int_tag_t +struct lv2_int_tag final : lv2_obj { - static const u32 id_base = 0x1000a; - static const u32 id_step = 0x10000; - static const u32 id_count = 8192; + static const u32 id_base = 0x0a000000; const u32 id; - std::shared_ptr handler; + std::shared_ptr handler; - lv2_int_tag_t(); + lv2_int_tag(); }; -struct lv2_int_serv_t +struct lv2_int_serv final : lv2_obj { static const u32 id_base = 0x0b000000; - static const u32 id_step = 0x100; - static const u32 id_count = 8192; const std::shared_ptr thread; @@ -30,7 +26,7 @@ struct lv2_int_serv_t const u64 arg1; const u64 arg2; - lv2_int_serv_t(const std::shared_ptr& thread, u64 arg1, u64 arg2); + lv2_int_serv(const std::shared_ptr& thread, u64 arg1, u64 arg2); void exec(); void join(ppu_thread& ppu, lv2_lock_t); diff --git a/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp b/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp index 3b1f6ba95d..9b2761c504 100644 --- a/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp @@ -14,7 +14,7 @@ logs::channel sys_lwcond("sys_lwcond", logs::level::notice); extern u64 get_system_time(); -void lv2_lwcond_t::notify(lv2_lock_t, cpu_thread* thread, const std::shared_ptr& mutex, bool mode2) +void lv2_lwcond::notify(lv2_lock_t, cpu_thread* thread, const std::shared_ptr& mutex, bool mode2) { auto& ppu = static_cast(*thread); @@ -37,7 +37,7 @@ s32 _sys_lwcond_create(vm::ptr lwcond_id, u32 lwmutex_id, vm::ptr(name); + *lwcond_id = idm::make(name); return CELL_OK; } @@ -48,7 +48,7 @@ s32 _sys_lwcond_destroy(u32 lwcond_id) LV2_LOCK; - const auto cond = idm::get(lwcond_id); + const auto cond = idm::get(lwcond_id); if (!cond) { @@ -60,7 +60,7 @@ s32 _sys_lwcond_destroy(u32 lwcond_id) return CELL_EBUSY; } - idm::remove(lwcond_id); + idm::remove(lwcond_id); return CELL_OK; } @@ -71,8 +71,8 @@ s32 _sys_lwcond_signal(u32 lwcond_id, u32 lwmutex_id, u32 ppu_thread_id, u32 mod LV2_LOCK; - const auto cond = idm::get(lwcond_id); - const auto mutex = idm::get(lwmutex_id); + const auto cond = idm::get(lwcond_id); + const auto mutex = idm::get(lwmutex_id); if (!cond || (lwmutex_id && !mutex)) { @@ -124,8 +124,8 @@ s32 _sys_lwcond_signal_all(u32 lwcond_id, u32 lwmutex_id, u32 mode) LV2_LOCK; - const auto cond = idm::get(lwcond_id); - const auto mutex = idm::get(lwmutex_id); + const auto cond = idm::get(lwcond_id); + const auto mutex = idm::get(lwmutex_id); if (!cond || (lwmutex_id && !mutex)) { @@ -162,8 +162,8 @@ s32 _sys_lwcond_queue_wait(ppu_thread& ppu, u32 lwcond_id, u32 lwmutex_id, u64 t LV2_LOCK; - const auto cond = idm::get(lwcond_id); - const auto mutex = idm::get(lwmutex_id); + const auto cond = idm::get(lwcond_id); + const auto mutex = idm::get(lwmutex_id); if (!cond || !mutex) { diff --git a/rpcs3/Emu/Cell/lv2/sys_lwcond.h b/rpcs3/Emu/Cell/lv2/sys_lwcond.h index 5638623961..19a1ebf5fe 100644 --- a/rpcs3/Emu/Cell/lv2/sys_lwcond.h +++ b/rpcs3/Emu/Cell/lv2/sys_lwcond.h @@ -17,22 +17,20 @@ struct sys_lwcond_t be_t lwcond_queue; // lwcond pseudo-id }; -struct lv2_lwcond_t +struct lv2_lwcond final : lv2_obj { static const u32 id_base = 0x97000000; - static const u32 id_step = 0x100; - static const u32 id_count = 8192; const u64 name; sleep_queue sq; - lv2_lwcond_t(u64 name) + lv2_lwcond(u64 name) : name(name) { } - void notify(lv2_lock_t, cpu_thread* thread, const std::shared_ptr& mutex, bool mode2); + void notify(lv2_lock_t, cpu_thread* thread, const std::shared_ptr& mutex, bool mode2); }; // Aux diff --git a/rpcs3/Emu/Cell/lv2/sys_lwmutex.cpp b/rpcs3/Emu/Cell/lv2/sys_lwmutex.cpp index 66f287f56b..7f8cde2ef1 100644 --- a/rpcs3/Emu/Cell/lv2/sys_lwmutex.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_lwmutex.cpp @@ -13,7 +13,7 @@ logs::channel sys_lwmutex("sys_lwmutex", logs::level::notice); extern u64 get_system_time(); -void lv2_lwmutex_t::unlock(lv2_lock_t) +void lv2_lwmutex::unlock(lv2_lock_t) { if (signaled) { @@ -48,7 +48,7 @@ s32 _sys_lwmutex_create(vm::ptr lwmutex_id, u32 protocol, vm::ptr(protocol, name); + *lwmutex_id = idm::make(protocol, name); return CELL_OK; } @@ -59,7 +59,7 @@ s32 _sys_lwmutex_destroy(u32 lwmutex_id) LV2_LOCK; - const auto mutex = idm::get(lwmutex_id); + const auto mutex = idm::get(lwmutex_id); if (!mutex) { @@ -71,7 +71,7 @@ s32 _sys_lwmutex_destroy(u32 lwmutex_id) return CELL_EBUSY; } - idm::remove(lwmutex_id); + idm::remove(lwmutex_id); return CELL_OK; } @@ -84,7 +84,7 @@ s32 _sys_lwmutex_lock(ppu_thread& ppu, u32 lwmutex_id, u64 timeout) LV2_LOCK; - const auto mutex = idm::get(lwmutex_id); + const auto mutex = idm::get(lwmutex_id); if (!mutex) { @@ -131,7 +131,7 @@ s32 _sys_lwmutex_trylock(u32 lwmutex_id) LV2_LOCK; - const auto mutex = idm::get(lwmutex_id); + const auto mutex = idm::get(lwmutex_id); if (!mutex) { @@ -154,7 +154,7 @@ s32 _sys_lwmutex_unlock(u32 lwmutex_id) LV2_LOCK; - const auto mutex = idm::get(lwmutex_id); + const auto mutex = idm::get(lwmutex_id); if (!mutex) { diff --git a/rpcs3/Emu/Cell/lv2/sys_lwmutex.h b/rpcs3/Emu/Cell/lv2/sys_lwmutex.h index 21773a5ce9..86d22657c2 100644 --- a/rpcs3/Emu/Cell/lv2/sys_lwmutex.h +++ b/rpcs3/Emu/Cell/lv2/sys_lwmutex.h @@ -44,11 +44,9 @@ struct sys_lwmutex_t be_t pad; }; -struct lv2_lwmutex_t +struct lv2_lwmutex final : lv2_obj { static const u32 id_base = 0x95000000; - static const u32 id_step = 0x100; - static const u32 id_count = 8192; const u32 protocol; const u64 name; @@ -58,7 +56,7 @@ struct lv2_lwmutex_t sleep_queue sq; - lv2_lwmutex_t(u32 protocol, u64 name) + lv2_lwmutex(u32 protocol, u64 name) : protocol(protocol) , name(name) { diff --git a/rpcs3/Emu/Cell/lv2/sys_mmapper.cpp b/rpcs3/Emu/Cell/lv2/sys_mmapper.cpp index 1a851671fc..096d6bbe7d 100644 --- a/rpcs3/Emu/Cell/lv2/sys_mmapper.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_mmapper.cpp @@ -103,7 +103,7 @@ error_code sys_mmapper_allocate_shared_memory(u64 unk, u32 size, u64 flags, vm:: } // Generate a new mem ID - *mem_id = idm::make(size, flags & SYS_MEMORY_PAGE_SIZE_1M ? 0x100000 : 0x10000, flags, dct); + *mem_id = idm::make(size, flags & SYS_MEMORY_PAGE_SIZE_1M ? 0x100000 : 0x10000, flags, dct); return CELL_OK; } @@ -163,7 +163,7 @@ error_code sys_mmapper_allocate_shared_memory_from_container(u64 unk, u32 size, } // Generate a new mem ID - *mem_id = idm::make(size, flags & SYS_MEMORY_PAGE_SIZE_1M ? 0x100000 : 0x10000, flags, ct.ptr); + *mem_id = idm::make(size, flags & SYS_MEMORY_PAGE_SIZE_1M ? 0x100000 : 0x10000, flags, ct.ptr); return CELL_OK; } @@ -200,7 +200,7 @@ error_code sys_mmapper_free_shared_memory(u32 mem_id) sys_mmapper.warning("sys_mmapper_free_shared_memory(mem_id=0x%x)", mem_id); // Conditionally remove memory ID - const auto mem = idm::withdraw(mem_id, [&](lv2_memory& mem) -> CellError + const auto mem = idm::withdraw(mem_id, [&](lv2_memory& mem) -> CellError { if (mem.addr.compare_and_swap_test(0, -1)) { @@ -237,7 +237,7 @@ error_code sys_mmapper_map_shared_memory(u32 addr, u32 mem_id, u64 flags) return CELL_EINVAL; } - const auto mem = idm::get(mem_id); + const auto mem = idm::get(mem_id); if (!mem) { @@ -276,7 +276,7 @@ error_code sys_mmapper_search_and_map(u32 start_addr, u32 mem_id, u64 flags, vm: return CELL_EINVAL; } - const auto mem = idm::get(mem_id); + const auto mem = idm::get(mem_id); if (!mem) { @@ -312,7 +312,7 @@ error_code sys_mmapper_unmap_shared_memory(u32 addr, vm::ptr mem_id) return CELL_EINVAL; } - const auto mem = idm::select([&](u32 id, lv2_memory& mem) + const auto mem = idm::select([&](u32 id, lv2_memory& mem) { if (mem.addr == addr) { diff --git a/rpcs3/Emu/Cell/lv2/sys_mmapper.h b/rpcs3/Emu/Cell/lv2/sys_mmapper.h index a24197b86e..88749178b4 100644 --- a/rpcs3/Emu/Cell/lv2/sys_mmapper.h +++ b/rpcs3/Emu/Cell/lv2/sys_mmapper.h @@ -1,12 +1,11 @@ #pragma once +#include "sys_sync.h" #include "sys_memory.h" -struct lv2_memory +struct lv2_memory : lv2_obj { static const u32 id_base = 0x08000000; - static const u32 id_step = 0x100; - static const u32 id_count = 8192; const u32 size; // Memory size const u32 align; // Alignment required diff --git a/rpcs3/Emu/Cell/lv2/sys_mutex.cpp b/rpcs3/Emu/Cell/lv2/sys_mutex.cpp index 29f098a02a..b87e2a6818 100644 --- a/rpcs3/Emu/Cell/lv2/sys_mutex.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_mutex.cpp @@ -13,7 +13,7 @@ logs::channel sys_mutex("sys_mutex", logs::level::notice); extern u64 get_system_time(); -void lv2_mutex_t::unlock(lv2_lock_t) +void lv2_mutex::unlock(lv2_lock_t) { owner.reset(); @@ -58,7 +58,7 @@ s32 sys_mutex_create(vm::ptr mutex_id, vm::ptr attr) return CELL_EINVAL; } - *mutex_id = idm::make(recursive, protocol, attr->name_u64); + *mutex_id = idm::make(recursive, protocol, attr->name_u64); return CELL_OK; } @@ -69,7 +69,7 @@ s32 sys_mutex_destroy(u32 mutex_id) LV2_LOCK; - const auto mutex = idm::get(mutex_id); + const auto mutex = idm::get(mutex_id); if (!mutex) { @@ -86,7 +86,7 @@ s32 sys_mutex_destroy(u32 mutex_id) return CELL_EPERM; } - idm::remove(mutex_id); + idm::remove(mutex_id); return CELL_OK; } @@ -99,7 +99,7 @@ s32 sys_mutex_lock(ppu_thread& ppu, u32 mutex_id, u64 timeout) LV2_LOCK; - const auto mutex = idm::get(mutex_id); + const auto mutex = idm::get(mutex_id); if (!mutex) { @@ -171,7 +171,7 @@ s32 sys_mutex_trylock(ppu_thread& ppu, u32 mutex_id) LV2_LOCK; - const auto mutex = idm::get(mutex_id); + const auto mutex = idm::get(mutex_id); if (!mutex) { @@ -213,7 +213,7 @@ s32 sys_mutex_unlock(ppu_thread& ppu, u32 mutex_id) LV2_LOCK; - const auto mutex = idm::get(mutex_id); + const auto mutex = idm::get(mutex_id); if (!mutex) { diff --git a/rpcs3/Emu/Cell/lv2/sys_mutex.h b/rpcs3/Emu/Cell/lv2/sys_mutex.h index bec1f9ab30..fa837ff624 100644 --- a/rpcs3/Emu/Cell/lv2/sys_mutex.h +++ b/rpcs3/Emu/Cell/lv2/sys_mutex.h @@ -19,11 +19,9 @@ struct sys_mutex_attribute_t }; }; -struct lv2_mutex_t +struct lv2_mutex final : lv2_obj { static const u32 id_base = 0x85000000; - static const u32 id_step = 0x100; - static const u32 id_count = 8192; const bool recursive; const u32 protocol; @@ -35,7 +33,7 @@ struct lv2_mutex_t sleep_queue sq; - lv2_mutex_t(bool recursive, u32 protocol, u64 name) + lv2_mutex(bool recursive, u32 protocol, u64 name) : recursive(recursive) , protocol(protocol) , name(name) diff --git a/rpcs3/Emu/Cell/lv2/sys_process.cpp b/rpcs3/Emu/Cell/lv2/sys_process.cpp index 81a448536b..20697d62f8 100644 --- a/rpcs3/Emu/Cell/lv2/sys_process.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_process.cpp @@ -69,30 +69,36 @@ s32 sys_process_exit(s32 status) return CELL_OK; } +template +u32 idm_get_count() +{ + return idm::select([&](u32, Get&) {}); +} + s32 sys_process_get_number_of_object(u32 object, vm::ptr nump) { sys_process.error("sys_process_get_number_of_object(object=0x%x, nump=*0x%x)", object, nump); switch(object) { - case SYS_MEM_OBJECT: *nump = idm::get_count(); break; - case SYS_MUTEX_OBJECT: *nump = idm::get_count(); break; - case SYS_COND_OBJECT: *nump = idm::get_count(); break; - case SYS_RWLOCK_OBJECT: *nump = idm::get_count(); break; - case SYS_INTR_TAG_OBJECT: *nump = idm::get_count(); break; - case SYS_INTR_SERVICE_HANDLE_OBJECT: *nump = idm::get_count(); break; - case SYS_EVENT_QUEUE_OBJECT: *nump = idm::get_count(); break; - case SYS_EVENT_PORT_OBJECT: *nump = idm::get_count(); break; + case SYS_MEM_OBJECT: *nump = idm_get_count(); break; + case SYS_MUTEX_OBJECT: *nump = idm_get_count(); break; + case SYS_COND_OBJECT: *nump = idm_get_count(); break; + case SYS_RWLOCK_OBJECT: *nump = idm_get_count(); break; + case SYS_INTR_TAG_OBJECT: *nump = idm_get_count(); break; + case SYS_INTR_SERVICE_HANDLE_OBJECT: *nump = idm_get_count(); break; + case SYS_EVENT_QUEUE_OBJECT: *nump = idm_get_count(); break; + case SYS_EVENT_PORT_OBJECT: *nump = idm_get_count(); break; case SYS_TRACE_OBJECT: fmt::throw_exception("SYS_TRACE_OBJECT" HERE); case SYS_SPUIMAGE_OBJECT: fmt::throw_exception("SYS_SPUIMAGE_OBJECT" HERE); - case SYS_PRX_OBJECT: *nump = idm::get_count(); break; + case SYS_PRX_OBJECT: *nump = idm_get_count(); break; case SYS_SPUPORT_OBJECT: fmt::throw_exception("SYS_SPUPORT_OBJECT" HERE); - case SYS_LWMUTEX_OBJECT: *nump = idm::get_count(); break; - case SYS_TIMER_OBJECT: *nump = idm::get_count(); break; - case SYS_SEMAPHORE_OBJECT: *nump = idm::get_count(); break; - case SYS_FS_FD_OBJECT: *nump = idm::get_count(); break; - case SYS_LWCOND_OBJECT: *nump = idm::get_count(); break; - case SYS_EVENT_FLAG_OBJECT: *nump = idm::get_count(); break; + case SYS_LWMUTEX_OBJECT: *nump = idm_get_count(); break; + case SYS_TIMER_OBJECT: *nump = idm_get_count(); break; + case SYS_SEMAPHORE_OBJECT: *nump = idm_get_count(); break; + case SYS_FS_FD_OBJECT: *nump = idm_get_count(); break; + case SYS_LWCOND_OBJECT: *nump = idm_get_count(); break; + case SYS_EVENT_FLAG_OBJECT: *nump = idm_get_count(); break; default: { @@ -105,10 +111,10 @@ s32 sys_process_get_number_of_object(u32 object, vm::ptr nump) #include -template +template void idm_get_set(std::set& out) { - idm::select([&](u32 id, T&) + idm::select([&](u32 id, Get&) { out.emplace(id); }); @@ -122,24 +128,24 @@ s32 sys_process_get_id(u32 object, vm::ptr buffer, u32 size, vm::ptr s switch (object) { - case SYS_MEM_OBJECT: idm_get_set(objects); break; - case SYS_MUTEX_OBJECT: idm_get_set(objects); break; - case SYS_COND_OBJECT: idm_get_set(objects); break; - case SYS_RWLOCK_OBJECT: idm_get_set(objects); break; - case SYS_INTR_TAG_OBJECT: idm_get_set(objects); break; - case SYS_INTR_SERVICE_HANDLE_OBJECT: idm_get_set(objects); break; - case SYS_EVENT_QUEUE_OBJECT: idm_get_set(objects); break; - case SYS_EVENT_PORT_OBJECT: idm_get_set(objects); break; + case SYS_MEM_OBJECT: idm_get_set(objects); break; + case SYS_MUTEX_OBJECT: idm_get_set(objects); break; + case SYS_COND_OBJECT: idm_get_set(objects); break; + case SYS_RWLOCK_OBJECT: idm_get_set(objects); break; + case SYS_INTR_TAG_OBJECT: idm_get_set(objects); break; + case SYS_INTR_SERVICE_HANDLE_OBJECT: idm_get_set(objects); break; + case SYS_EVENT_QUEUE_OBJECT: idm_get_set(objects); break; + case SYS_EVENT_PORT_OBJECT: idm_get_set(objects); break; case SYS_TRACE_OBJECT: fmt::throw_exception("SYS_TRACE_OBJECT" HERE); case SYS_SPUIMAGE_OBJECT: fmt::throw_exception("SYS_SPUIMAGE_OBJECT" HERE); - case SYS_PRX_OBJECT: idm_get_set(objects); break; + case SYS_PRX_OBJECT: idm_get_set(objects); break; case SYS_SPUPORT_OBJECT: fmt::throw_exception("SYS_SPUPORT_OBJECT" HERE); - case SYS_LWMUTEX_OBJECT: idm_get_set(objects); break; - case SYS_TIMER_OBJECT: idm_get_set(objects); break; - case SYS_SEMAPHORE_OBJECT: idm_get_set(objects); break; - case SYS_FS_FD_OBJECT: idm_get_set(objects); break; - case SYS_LWCOND_OBJECT: idm_get_set(objects); break; - case SYS_EVENT_FLAG_OBJECT: idm_get_set(objects); break; + case SYS_LWMUTEX_OBJECT: idm_get_set(objects); break; + case SYS_TIMER_OBJECT: idm_get_set(objects); break; + case SYS_SEMAPHORE_OBJECT: idm_get_set(objects); break; + case SYS_FS_FD_OBJECT: idm_get_set(objects); break; + case SYS_LWCOND_OBJECT: idm_get_set(objects); break; + case SYS_EVENT_FLAG_OBJECT: idm_get_set(objects); break; default: { diff --git a/rpcs3/Emu/Cell/lv2/sys_prx.cpp b/rpcs3/Emu/Cell/lv2/sys_prx.cpp index 31912cd02d..fe86bc5fe8 100644 --- a/rpcs3/Emu/Cell/lv2/sys_prx.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_prx.cpp @@ -10,7 +10,7 @@ namespace vm { using namespace ps3; } -extern std::shared_ptr ppu_load_prx(const ppu_prx_object&); +extern std::shared_ptr ppu_load_prx(const ppu_prx_object&); logs::channel sys_prx("sys_prx", logs::level::notice); @@ -83,7 +83,7 @@ s32 sys_prx_start_module(s32 id, u64 flags, vm::ptr(id); + const auto prx = idm::get(id); if (!prx) { @@ -103,7 +103,7 @@ s32 sys_prx_stop_module(s32 id, u64 flags, vm::ptr { sys_prx.warning("sys_prx_stop_module(id=0x%x, flags=0x%llx, pOpt=*0x%x)", id, flags, pOpt); - const auto prx = idm::get(id); + const auto prx = idm::get(id); if (!prx) { @@ -124,7 +124,7 @@ s32 sys_prx_unload_module(s32 id, u64 flags, vm::ptr(id); + const auto prx = idm::get(id); if (!prx) { @@ -134,7 +134,7 @@ s32 sys_prx_unload_module(s32 id, u64 flags, vm::ptraddress); //s32 result = prx->exit ? prx->exit() : CELL_OK; - idm::remove(id); + idm::remove(id); return CELL_OK; } @@ -232,7 +232,7 @@ s32 sys_prx_stop() return CELL_OK; } -lv2_prx_t::lv2_prx_t() +lv2_prx::lv2_prx() : id(idm::last_id()) { } diff --git a/rpcs3/Emu/Cell/lv2/sys_prx.h b/rpcs3/Emu/Cell/lv2/sys_prx.h index e1ec1228cf..00e2317617 100644 --- a/rpcs3/Emu/Cell/lv2/sys_prx.h +++ b/rpcs3/Emu/Cell/lv2/sys_prx.h @@ -1,6 +1,7 @@ #pragma once #include "Emu/Cell/PPUAnalyser.h" +#include "sys_sync.h" // Return codes enum @@ -72,11 +73,9 @@ struct sys_prx_get_module_list_t vm::ps3::bptr idlist; }; -struct lv2_prx_t +struct lv2_prx final : lv2_obj { static const u32 id_base = 0x23000000; - static const u32 id_step = 0x100; - static const u32 id_count = 8192; const u32 id; @@ -89,7 +88,7 @@ struct lv2_prx_t vm::ps3::ptr argv)> stop = vm::null; vm::ps3::ptr exit = vm::null; - lv2_prx_t(); + lv2_prx(); }; // SysCalls diff --git a/rpcs3/Emu/Cell/lv2/sys_rwlock.cpp b/rpcs3/Emu/Cell/lv2/sys_rwlock.cpp index 5424b3df0c..6b53fcdf0f 100644 --- a/rpcs3/Emu/Cell/lv2/sys_rwlock.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_rwlock.cpp @@ -13,7 +13,7 @@ logs::channel sys_rwlock("sys_rwlock", logs::level::notice); extern u64 get_system_time(); -void lv2_rwlock_t::notify_all(lv2_lock_t) +void lv2_rwlock::notify_all(lv2_lock_t) { // pick a new writer if possible; protocol is ignored in current implementation if (!readers && !writer && wsq.size()) @@ -61,7 +61,7 @@ s32 sys_rwlock_create(vm::ptr rw_lock_id, vm::ptr a return CELL_EINVAL; } - *rw_lock_id = idm::make(protocol, attr->name_u64); + *rw_lock_id = idm::make(protocol, attr->name_u64); return CELL_OK; } @@ -72,7 +72,7 @@ s32 sys_rwlock_destroy(u32 rw_lock_id) LV2_LOCK; - const auto rwlock = idm::get(rw_lock_id); + const auto rwlock = idm::get(rw_lock_id); if (!rwlock) { @@ -84,7 +84,7 @@ s32 sys_rwlock_destroy(u32 rw_lock_id) return CELL_EBUSY; } - idm::remove(rw_lock_id); + idm::remove(rw_lock_id); return CELL_OK; } @@ -97,7 +97,7 @@ s32 sys_rwlock_rlock(ppu_thread& ppu, u32 rw_lock_id, u64 timeout) LV2_LOCK; - const auto rwlock = idm::get(rw_lock_id); + const auto rwlock = idm::get(rw_lock_id); if (!rwlock) { @@ -152,7 +152,7 @@ s32 sys_rwlock_tryrlock(u32 rw_lock_id) LV2_LOCK; - const auto rwlock = idm::get(rw_lock_id); + const auto rwlock = idm::get(rw_lock_id); if (!rwlock) { @@ -178,7 +178,7 @@ s32 sys_rwlock_runlock(u32 rw_lock_id) LV2_LOCK; - const auto rwlock = idm::get(rw_lock_id); + const auto rwlock = idm::get(rw_lock_id); if (!rwlock) { @@ -206,7 +206,7 @@ s32 sys_rwlock_wlock(ppu_thread& ppu, u32 rw_lock_id, u64 timeout) LV2_LOCK; - const auto rwlock = idm::get(rw_lock_id); + const auto rwlock = idm::get(rw_lock_id); if (!rwlock) { @@ -275,7 +275,7 @@ s32 sys_rwlock_trywlock(ppu_thread& ppu, u32 rw_lock_id) LV2_LOCK; - const auto rwlock = idm::get(rw_lock_id); + const auto rwlock = idm::get(rw_lock_id); if (!rwlock) { @@ -303,7 +303,7 @@ s32 sys_rwlock_wunlock(ppu_thread& ppu, u32 rw_lock_id) LV2_LOCK; - const auto rwlock = idm::get(rw_lock_id); + const auto rwlock = idm::get(rw_lock_id); if (!rwlock) { diff --git a/rpcs3/Emu/Cell/lv2/sys_rwlock.h b/rpcs3/Emu/Cell/lv2/sys_rwlock.h index 7ebf3e6eec..7258a1916e 100644 --- a/rpcs3/Emu/Cell/lv2/sys_rwlock.h +++ b/rpcs3/Emu/Cell/lv2/sys_rwlock.h @@ -17,11 +17,9 @@ struct sys_rwlock_attribute_t }; }; -struct lv2_rwlock_t +struct lv2_rwlock final : lv2_obj { static const u32 id_base = 0x88000000; - static const u32 id_step = 0x100; - static const u32 id_count = 8192; const u64 name; const u32 protocol; @@ -32,7 +30,7 @@ struct lv2_rwlock_t sleep_queue rsq; // threads trying to acquire readed lock sleep_queue wsq; // threads trying to acquire writer lock - lv2_rwlock_t(u32 protocol, u64 name) + lv2_rwlock(u32 protocol, u64 name) : protocol(protocol) , name(name) { diff --git a/rpcs3/Emu/Cell/lv2/sys_semaphore.cpp b/rpcs3/Emu/Cell/lv2/sys_semaphore.cpp index a72a221d16..b5405bd8e1 100644 --- a/rpcs3/Emu/Cell/lv2/sys_semaphore.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_semaphore.cpp @@ -42,7 +42,7 @@ s32 sys_semaphore_create(vm::ptr sem_id, vm::ptr return CELL_EINVAL; } - *sem_id = idm::make(protocol, max_val, attr->name_u64, initial_val); + *sem_id = idm::make(protocol, max_val, attr->name_u64, initial_val); return CELL_OK; } @@ -53,7 +53,7 @@ s32 sys_semaphore_destroy(u32 sem_id) LV2_LOCK; - const auto sem = idm::get(sem_id); + const auto sem = idm::get(sem_id); if (!sem) { @@ -65,7 +65,7 @@ s32 sys_semaphore_destroy(u32 sem_id) return CELL_EBUSY; } - idm::remove(sem_id); + idm::remove(sem_id); return CELL_OK; } @@ -78,7 +78,7 @@ s32 sys_semaphore_wait(ppu_thread& ppu, u32 sem_id, u64 timeout) LV2_LOCK; - const auto sem = idm::get(sem_id); + const auto sem = idm::get(sem_id); if (!sem) { @@ -125,7 +125,7 @@ s32 sys_semaphore_trywait(u32 sem_id) LV2_LOCK; - const auto sem = idm::get(sem_id); + const auto sem = idm::get(sem_id); if (!sem) { @@ -148,7 +148,7 @@ s32 sys_semaphore_post(u32 sem_id, s32 count) LV2_LOCK; - const auto sem = idm::get(sem_id); + const auto sem = idm::get(sem_id); if (!sem) { @@ -197,7 +197,7 @@ s32 sys_semaphore_get_value(u32 sem_id, vm::ptr count) return CELL_EFAULT; } - const auto sem = idm::get(sem_id); + const auto sem = idm::get(sem_id); if (!sem) { diff --git a/rpcs3/Emu/Cell/lv2/sys_semaphore.h b/rpcs3/Emu/Cell/lv2/sys_semaphore.h index 533e80f4da..b16e4a2786 100644 --- a/rpcs3/Emu/Cell/lv2/sys_semaphore.h +++ b/rpcs3/Emu/Cell/lv2/sys_semaphore.h @@ -17,11 +17,9 @@ struct sys_semaphore_attribute_t }; }; -struct lv2_sema_t +struct lv2_sema final : lv2_obj { static const u32 id_base = 0x96000000; - static const u32 id_step = 0x100; - static const u32 id_count = 8192; const u32 protocol; const s32 max; @@ -31,7 +29,7 @@ struct lv2_sema_t sleep_queue sq; - lv2_sema_t(u32 protocol, s32 max, u64 name, s32 value) + lv2_sema(u32 protocol, s32 max, u64 name, s32 value) : protocol(protocol) , max(max) , name(name) diff --git a/rpcs3/Emu/Cell/lv2/sys_spu.cpp b/rpcs3/Emu/Cell/lv2/sys_spu.cpp index 5420062d9f..2ac66af183 100644 --- a/rpcs3/Emu/Cell/lv2/sys_spu.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_spu.cpp @@ -99,7 +99,7 @@ u32 spu_thread_initialize(u32 group_id, u32 spu_num, vm::ptr im spu->custom_task = task; - const auto group = idm::get(group_id); + const auto group = idm::get(group_id); spu->tg = group; group->threads[spu_num] = spu; @@ -135,7 +135,7 @@ s32 sys_spu_thread_initialize(vm::ptr thread, u32 group_id, u32 spu_num, vm LV2_LOCK; - const auto group = idm::get(group_id); + const auto group = idm::get(group_id); if (!group) { @@ -225,7 +225,7 @@ s32 sys_spu_thread_group_create(vm::ptr id, u32 num, s32 prio, vm::ptrtype); } - *id = idm::make(std::string(attr->name.get_ptr(), attr->nsize - 1), num, prio, attr->type, attr->ct); + *id = idm::make(std::string(attr->name.get_ptr(), attr->nsize - 1), num, prio, attr->type, attr->ct); return CELL_OK; } @@ -236,7 +236,7 @@ s32 sys_spu_thread_group_destroy(u32 id) LV2_LOCK; - const auto group = idm::get(id); + const auto group = idm::get(id); if (!group) { @@ -260,7 +260,7 @@ s32 sys_spu_thread_group_destroy(u32 id) } group->state = SPU_THREAD_GROUP_STATUS_NOT_INITIALIZED; // hack - idm::remove(id); + idm::remove(id); return CELL_OK; } @@ -271,7 +271,7 @@ s32 sys_spu_thread_group_start(u32 id) LV2_LOCK; - const auto group = idm::get(id); + const auto group = idm::get(id); if (!group) { @@ -336,7 +336,7 @@ s32 sys_spu_thread_group_suspend(u32 id) LV2_LOCK; - const auto group = idm::get(id); + const auto group = idm::get(id); if (!group) { @@ -389,7 +389,7 @@ s32 sys_spu_thread_group_resume(u32 id) LV2_LOCK; - const auto group = idm::get(id); + const auto group = idm::get(id); if (!group) { @@ -436,7 +436,7 @@ s32 sys_spu_thread_group_yield(u32 id) LV2_LOCK; - const auto group = idm::get(id); + const auto group = idm::get(id); if (!group) { @@ -466,7 +466,7 @@ s32 sys_spu_thread_group_terminate(u32 id, s32 value) // seems the id can be either SPU Thread Group or SPU Thread const auto thread = idm::get(id); - const auto group = thread ? thread->tg.lock() : idm::get(id); + const auto group = thread ? thread->tg.lock() : idm::get(id); if (!group && !thread) { @@ -522,7 +522,7 @@ s32 sys_spu_thread_group_join(u32 id, vm::ptr cause, vm::ptr status) LV2_LOCK; - const auto group = idm::get(id); + const auto group = idm::get(id); if (!group) { @@ -795,8 +795,8 @@ s32 sys_spu_thread_group_connect_event(u32 id, u32 eq, u32 et) LV2_LOCK; - const auto group = idm::get(id); - const auto queue = idm::get(eq); + const auto group = idm::get(id); + const auto queue = idm::get(eq); if (!group || !queue) { @@ -851,7 +851,7 @@ s32 sys_spu_thread_group_disconnect_event(u32 id, u32 et) LV2_LOCK; - const auto group = idm::get(id); + const auto group = idm::get(id); if (!group) { @@ -907,7 +907,7 @@ s32 sys_spu_thread_connect_event(u32 id, u32 eq, u32 et, u8 spup) LV2_LOCK; const auto thread = idm::get(id); - const auto queue = idm::get(eq); + const auto queue = idm::get(eq); if (!thread || !queue) { @@ -970,7 +970,7 @@ s32 sys_spu_thread_bind_queue(u32 id, u32 spuq, u32 spuq_num) LV2_LOCK; const auto thread = idm::get(id); - const auto queue = idm::get(spuq); + const auto queue = idm::get(spuq); if (!thread || !queue) { @@ -1039,8 +1039,8 @@ s32 sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq, u64 req, vm:: LV2_LOCK; - const auto group = idm::get(id); - const auto queue = idm::get(eq); + const auto group = idm::get(id); + const auto queue = idm::get(eq); if (!group || !queue) { @@ -1110,7 +1110,7 @@ s32 sys_spu_thread_group_disconnect_event_all_threads(u32 id, u8 spup) LV2_LOCK; - const auto group = idm::get(id); + const auto group = idm::get(id); if (!group) { @@ -1183,7 +1183,7 @@ s32 sys_raw_spu_destroy(ppu_thread& ppu, u32 id) intr.tag->handler->join(ppu, lv2_lock); } - idm::remove(intr.tag->id); + idm::remove(intr.tag->id); } } @@ -1217,7 +1217,7 @@ s32 sys_raw_spu_create_interrupt_tag(u32 id, u32 class_id, u32 hwthread, vm::ptr return CELL_EAGAIN; } - int_ctrl.tag = idm::make_ptr(); + int_ctrl.tag = idm::make_ptr(); *intrtag = int_ctrl.tag->id; diff --git a/rpcs3/Emu/Cell/lv2/sys_spu.h b/rpcs3/Emu/Cell/lv2/sys_spu.h index 2e3708b9cc..b8e417c748 100644 --- a/rpcs3/Emu/Cell/lv2/sys_spu.h +++ b/rpcs3/Emu/Cell/lv2/sys_spu.h @@ -137,11 +137,11 @@ enum : u32 class SPUThread; -struct lv2_spu_group_t +struct lv2_spu_group { static const u32 id_base = 1; // Wrong? static const u32 id_step = 1; - static const u32 id_count = 8192; + static const u32 id_count = 255; const std::string name; const u32 num; // SPU Number @@ -159,11 +159,11 @@ struct lv2_spu_group_t atomic_t join_state; // flags used to detect exit cause cond_variable cv; // used to signal waiting PPU thread - std::weak_ptr ep_run; // port for SYS_SPU_THREAD_GROUP_EVENT_RUN events - std::weak_ptr ep_exception; // TODO: SYS_SPU_THREAD_GROUP_EVENT_EXCEPTION - std::weak_ptr ep_sysmodule; // TODO: SYS_SPU_THREAD_GROUP_EVENT_SYSTEM_MODULE + std::weak_ptr ep_run; // port for SYS_SPU_THREAD_GROUP_EVENT_RUN events + std::weak_ptr ep_exception; // TODO: SYS_SPU_THREAD_GROUP_EVENT_EXCEPTION + std::weak_ptr ep_sysmodule; // TODO: SYS_SPU_THREAD_GROUP_EVENT_SYSTEM_MODULE - lv2_spu_group_t(std::string name, u32 num, s32 prio, s32 type, u32 ct) + lv2_spu_group(std::string name, u32 num, s32 prio, s32 type, u32 ct) : name(name) , num(num) , prio(prio) diff --git a/rpcs3/Emu/Cell/lv2/sys_sync.h b/rpcs3/Emu/Cell/lv2/sys_sync.h index 80ae855f62..d39ab4d253 100644 --- a/rpcs3/Emu/Cell/lv2/sys_sync.h +++ b/rpcs3/Emu/Cell/lv2/sys_sync.h @@ -45,6 +45,15 @@ enum SYS_SYNC_NOT_ADAPTIVE = 0x2000, }; +// Base class for some kernel objects (shared set of 8192 objects). +struct lv2_obj +{ + using id_type = lv2_obj; + + static const u32 id_step = 0x100; + static const u32 id_count = 8192; +}; + // Temporary implementation for LV2_UNLOCK (TODO: remove it) struct lv2_lock_guard { diff --git a/rpcs3/Emu/Cell/lv2/sys_timer.cpp b/rpcs3/Emu/Cell/lv2/sys_timer.cpp index d2d9f623fd..88a7cbc25e 100644 --- a/rpcs3/Emu/Cell/lv2/sys_timer.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_timer.cpp @@ -14,7 +14,7 @@ logs::channel sys_timer("sys_timer", logs::level::notice); extern u64 get_system_time(); -void lv2_timer_t::on_task() +void lv2_timer::on_task() { //thread_lock lock(*this); LV2_LOCK; @@ -57,12 +57,12 @@ void lv2_timer_t::on_task() } } -std::string lv2_timer_t::get_name() const +std::string lv2_timer::get_name() const { return fmt::format("Timer Thread[0x%x]", id); } -void lv2_timer_t::on_stop() +void lv2_timer::on_stop() { // Signal thread using invalid state and join state = -1; @@ -74,7 +74,7 @@ s32 sys_timer_create(vm::ptr timer_id) { sys_timer.warning("sys_timer_create(timer_id=*0x%x)", timer_id); - *timer_id = idm::make(); + *timer_id = idm::make(); return CELL_OK; } @@ -85,7 +85,7 @@ s32 sys_timer_destroy(u32 timer_id) LV2_LOCK; - const auto timer = idm::get(timer_id); + const auto timer = idm::get(timer_id); if (!timer) { @@ -97,7 +97,7 @@ s32 sys_timer_destroy(u32 timer_id) return CELL_EISCONN; } - idm::remove(timer_id); + idm::remove(timer_id); return CELL_OK; } @@ -108,7 +108,7 @@ s32 sys_timer_get_information(u32 timer_id, vm::ptr inf LV2_LOCK; - const auto timer = idm::get(timer_id); + const auto timer = idm::get(timer_id); if (!timer) { @@ -131,7 +131,7 @@ s32 _sys_timer_start(u32 timer_id, u64 base_time, u64 period) LV2_LOCK; - const auto timer = idm::get(timer_id); + const auto timer = idm::get(timer_id); if (!timer) { @@ -182,7 +182,7 @@ s32 sys_timer_stop(u32 timer_id) LV2_LOCK; - const auto timer = idm::get(timer_id); + const auto timer = idm::get(timer_id); if (!timer) { @@ -200,8 +200,8 @@ s32 sys_timer_connect_event_queue(u32 timer_id, u32 queue_id, u64 name, u64 data LV2_LOCK; - const auto timer = idm::get(timer_id); - const auto queue = idm::get(queue_id); + const auto timer = idm::get(timer_id); + const auto queue = idm::get(queue_id); if (!timer || !queue) { @@ -227,7 +227,7 @@ s32 sys_timer_disconnect_event_queue(u32 timer_id) LV2_LOCK; - const auto timer = idm::get(timer_id); + const auto timer = idm::get(timer_id); if (!timer) { diff --git a/rpcs3/Emu/Cell/lv2/sys_timer.h b/rpcs3/Emu/Cell/lv2/sys_timer.h index 34550e2fd2..323a774de1 100644 --- a/rpcs3/Emu/Cell/lv2/sys_timer.h +++ b/rpcs3/Emu/Cell/lv2/sys_timer.h @@ -17,14 +17,12 @@ struct sys_timer_information_t be_t pad; }; -class lv2_timer_t final : public named_thread +class lv2_timer final : public lv2_obj, public named_thread { void on_task() override; public: static const u32 id_base = 0x11000000; - static const u32 id_step = 0x100; - static const u32 id_count = 8192; std::string get_name() const override; @@ -34,7 +32,7 @@ public: atomic_t state{ SYS_TIMER_STATE_RUN }; // Timer state - std::weak_ptr port; // Event queue + std::weak_ptr port; // Event queue u64 source; // Event source u64 data1; // Event arg 1 u64 data2; // Event arg 2 diff --git a/rpcs3/Emu/IdManager.cpp b/rpcs3/Emu/IdManager.cpp index c2bf6c1d06..da20e32d8f 100644 --- a/rpcs3/Emu/IdManager.cpp +++ b/rpcs3/Emu/IdManager.cpp @@ -7,136 +7,86 @@ thread_local DECLARE(idm::g_id); DECLARE(idm::g_map); DECLARE(fxm::g_vec); -std::vector& id_manager::typeinfo::access() +id_manager::id_map::pointer idm::allocate_id(const id_manager::id_key& info, u32 base, u32 step, u32 count) { - static std::vector list; - - return list; -} + // Base type id is stored in value + auto& vec = g_map[info.value()]; -u32 id_manager::typeinfo::add_type() -{ - auto& list = access(); + // Preallocate memory + vec.reserve(count); - list.emplace_back(); - - return ::size32(list) - 1; -} - -id_manager::id_map::pointer idm::allocate_id(std::pair types, u32 base, u32 step, u32 count) -{ - auto& map = g_map[types.first]; - - // Assume next ID - u32 next = base; - - if (std::size_t _count = map.size()) + if (vec.size() < count) { - if (_count >= count) - { - return nullptr; - } + // Try to emplace back + const u32 _next = base + step * ::size32(vec); - const u32 _next = next + step * count; - - if (_next > base && _next < base + step * count) + if (_next >= base && _next < base + step * count) { - next = _next; + g_id = _next; + vec.emplace_back(id_manager::id_key(_next, info.type(), info.on_stop()), nullptr); + return &vec.back(); } } // Check all IDs starting from "next id" (TODO) - for (u32 i = 0; i < count; i++, next += step) + for (u32 i = 0, next = base; i < count; i++, next += step) { - // Get correct ID value - if (next >= base + step * count) - { - next = base; - } + const auto ptr = &vec[i]; - // Try to allocate ID storage - const auto result = map.emplace(id_manager::id_key(next, types.second), nullptr); - - if (result.second) + // Look for free ID + if (!ptr->second) { - // Acknowledge the ID g_id = next; - - return std::addressof(*result.first); + ptr->first = id_manager::id_key(next, info.type(), info.on_stop()); + return ptr; } } - // Nothing found + // Out of IDs return nullptr; } -id_manager::id_map::const_pointer idm::find_id(u32 type, u32 true_type, u32 id) -{ - const auto& map = g_map[type]; - - const auto found = map.find(id); - - if (found != map.end() && (type == true_type || found->first.type() == true_type)) - { - return std::addressof(*found); - } - - return nullptr; -} - -std::shared_ptr idm::delete_id(u32 type, u32 true_type, u32 id) -{ - auto& map = g_map[type]; - - const auto found = map.find(id); - - std::shared_ptr result; - - if (found != map.end() && (type == true_type || found->first.type() == true_type)) - { - result = std::move(found->second); - map.erase(found); - } - - return result; -} - void idm::init() { - g_map.resize(id_manager::typeinfo::get().size()); + // Allocate + g_map.resize(id_manager::typeinfo::get_count()); } void idm::clear() { // Call recorded finalization functions for all IDs - for (std::size_t i = 0; i < g_map.size(); i++) + for (auto& map : g_map) { - const auto on_stop = id_manager::typeinfo::get()[i].on_stop; - - for (auto& id : g_map[i]) + for (auto& pair : map) { - on_stop(id.second.get()); + if (auto ptr = pair.second.get()) + { + pair.first.on_stop()(ptr); + pair.second.reset(); + pair.first = {}; + } } - g_map[i].clear(); + map.clear(); } } void fxm::init() { - g_vec.resize(id_manager::typeinfo::get().size(), {}); + // Allocate + g_vec.resize(id_manager::typeinfo::get_count()); } void fxm::clear() { // Call recorded finalization functions for all IDs - for (std::size_t i = 0; i < g_vec.size(); i++) + for (auto& pair : g_vec) { - if (g_vec[i]) + if (auto ptr = pair.second.get()) { - id_manager::typeinfo::get()[i].on_stop(g_vec[i].get()); + pair.first(ptr); + pair.second.reset(); + pair.first = nullptr; } - - g_vec[i].reset(); } } diff --git a/rpcs3/Emu/IdManager.h b/rpcs3/Emu/IdManager.h index 17460ea301..046edd429b 100644 --- a/rpcs3/Emu/IdManager.h +++ b/rpcs3/Emu/IdManager.h @@ -5,39 +5,38 @@ #include #include -#include -// idm/fxm: helper namespace +// Helper namespace namespace id_manager { // Common global mutex extern shared_mutex g_mutex; - // Optional ID traits - template + // ID traits + template struct id_traits { static_assert(sizeof(T) == 0, "ID object must specify: id_base, id_step, id_count"); - static const u32 base = 1; // First ID (N = 0) - static const u32 step = 1; // Any ID: N * id_step + id_base - static const u32 count = 65535; // Limit: N < id_count + static const u32 base = 1; // First ID (N = 0) + static const u32 step = 1; // Any ID: N * id_step + id_base + static const u32 count = 65535; // Limit: N < id_count static const u32 invalid = 0; }; - template + template struct id_traits> { - static const u32 base = T::id_base; - static const u32 step = T::id_step; - static const u32 count = T::id_count; + static const u32 base = T::id_base; + static const u32 step = T::id_step; + static const u32 count = T::id_count; static const u32 invalid = base > 0 ? 0 : -1; static_assert(u64{step} * count + base < UINT32_MAX, "ID traits: invalid object range"); }; // Optional object initialization function (called after ID registration) - template + template struct on_init { static inline void func(T*, const std::shared_ptr&) @@ -47,17 +46,17 @@ namespace id_manager } }; - template + template struct on_init().on_init(std::declval&>()))> { - static inline void func(T* ptr, const std::shared_ptr&_ptr) + static inline void func(T* ptr, const std::shared_ptr& _ptr) { if (ptr) ptr->on_init(_ptr); } }; // Optional object finalization function (called after ID removal) - template + template struct on_stop { static inline void func(T*) @@ -67,7 +66,7 @@ namespace id_manager } }; - template + template struct on_stop().on_stop())> { static inline void func(T* ptr) @@ -76,64 +75,82 @@ namespace id_manager } }; + // Correct usage testing + template + struct id_verify : std::integral_constant::value> + { + // If common case, T2 shall be derived from or equal to T + }; + + template + struct id_verify> : std::integral_constant::value> + { + // If T2 contains id_type type, T must be equal to it + }; + class typeinfo { // Global variable for each registered type - template + template struct registered { static const u32 index; }; - // Access global type list - static std::vector& access(); + // Increment type counter + static u32 add_type(u32 i) + { + static atomic_t g_next{0}; - // Add to the global list - static u32 add_type(); + return g_next.fetch_add(i); + } public: - void(*on_stop)(void*) = nullptr; - // Get type index - template + template static inline u32 get_index() { return registered::index; } - // Register functions - template - static inline void update() + // Get type count + static inline u32 get_count() { - access()[get_index()].on_stop = [](void* ptr) { return id_manager::on_stop::func(static_cast(ptr)); }; + return add_type(0); } - // Read all registered types - static inline const auto& get() + // Get type finalizer + template + static inline auto get_stop() { - return access(); + return [](void* ptr) -> void + { + return id_manager::on_stop::func(static_cast(ptr)); + }; } }; - template - const u32 typeinfo::registered::index = typeinfo::add_type(); + template + const u32 typeinfo::registered::index = typeinfo::add_type(1); // ID value with additional type stored class id_key { - u32 m_value; // ID value - u32 m_type; // True object type + u32 m_value; // ID value + u32 m_type; // True object type + void (*m_stop)(void*); // Finalizer public: id_key() = default; - id_key(u32 value, u32 type = 0) + id_key(u32 value, u32 type, void (*stop)(void*)) : m_value(value) , m_type(type) + , m_stop(stop) { } - u32 id() const + u32 value() const { return m_value; } @@ -143,21 +160,18 @@ namespace id_manager return m_type; } + auto on_stop() const + { + return m_stop; + } + operator u32() const { return m_value; } }; - struct id_hash - { - std::size_t operator()(const id_key& id) const - { - return id ^ (id >> 8); - } - }; - - using id_map = std::unordered_map, id_hash>; + using id_map = std::vector>>; } // Object manager for emulated process. Multiple objects of specified arbitrary type are given unique IDs. @@ -169,46 +183,52 @@ class idm // Type Index -> ID -> Object. Use global since only one process is supported atm. static std::vector g_map; - template + template static inline u32 get_type() { return id_manager::typeinfo::get_index(); } + template + static constexpr u32 get_index(u32 id) + { + return (id - id_manager::id_traits::base) / id_manager::id_traits::step; + } + // Helper - template + template struct function_traits; - template - struct function_traits + template + struct function_traits { using object_type = A2; using result_type = R; }; - template - struct function_traits + template + struct function_traits { using object_type = A2; using result_type = R; }; - template - struct function_traits + template + struct function_traits { using object_type = A2; - using void_type = void; + using void_type = void; }; - template - struct function_traits + template + struct function_traits { using object_type = A2; - using void_type = void; + using void_type = void; }; // Helper - template + template struct return_pair { std::shared_ptr ptr; @@ -225,7 +245,7 @@ class idm } }; - template + template struct return_pair { bool result; @@ -238,40 +258,54 @@ class idm }; // Prepare new ID (returns nullptr if out of resources) - static id_manager::id_map::pointer allocate_id(std::pair types, u32 base, u32 step, u32 count); + static id_manager::id_map::pointer allocate_id(const id_manager::id_key& info, u32 base, u32 step, u32 count); - // Remove ID and return the object (additionally check true_type if not equal) - static std::shared_ptr delete_id(u32 type, u32 true_type, u32 id); + // Find ID (additionally check type if types are not equal) + template + static id_manager::id_map::pointer find_id(u32 id) + { + static_assert(id_manager::id_verify::value, "Invalid ID type combination"); - // Get ID (additionally check true_type if not equal) - static id_manager::id_map::const_pointer find_id(u32 type, u32 true_type, u32 id); + const u32 index = get_index(id); + + auto& vec = g_map[get_type()]; + + if (index >= vec.size() || index >= id_manager::id_traits::count) + { + return nullptr; + } + + if (const auto ptr = &vec[index]) + { + if (std::is_same::value || ptr->first.type() == get_type()) + { + return ptr; + } + } + + return nullptr; + } // Allocate new ID and assign the object from the provider() - template + template static id_manager::id_map::pointer create_id(F&& provider) { - writer_lock lock(id_manager::g_mutex); + static_assert(id_manager::id_verify::value, "Invalid ID type combination"); - // Register destructors - id_manager::typeinfo::update(); + // ID info + const id_manager::id_key info{get_type(), get_type(), id_manager::typeinfo::get_stop()}; - // Type IDs - std::pair types(get_type(), get_type()); + // ID traits + using traits = id_manager::id_traits; // Allocate new id - if (auto* place = allocate_id(types, id_manager::id_traits::base, id_manager::id_traits::step, id_manager::id_traits::count)) + writer_lock lock(id_manager::g_mutex); + + if (auto* place = allocate_id(info, traits::base, traits::step, traits::count)) { - try - { - // Get object, store it - place->second = provider(); - return place; - } - catch (...) - { - delete_id(types.first, types.first, place->first.id()); - throw; - } + // Get object, store it + place->second = provider(); + return place; } return nullptr; @@ -284,84 +318,80 @@ public: // Remove all objects static void clear(); - // Get last ID + // Get last ID (updated in create_id/allocate_id) static inline u32 last_id() { return g_id; } // Add a new ID of specified type with specified constructor arguments (returns object or nullptr) - template + template static inline std::enable_if_t::value, std::shared_ptr> make_ptr(Args&&... args) { if (auto pair = create_id([&] { return std::make_shared(std::forward(args)...); })) { - id_manager::on_init::func(static_cast(pair->second.get()), pair->second); - id_manager::on_stop::func(nullptr); - return{ pair->second, static_cast(pair->second.get()) }; + id_manager::on_init::func(static_cast(pair->second.get()), pair->second); + return {pair->second, static_cast(pair->second.get())}; } return nullptr; } // Add a new ID of specified type with specified constructor arguments (returns id) - template + template static inline std::enable_if_t::value, u32> make(Args&&... args) { if (auto pair = create_id([&] { return std::make_shared(std::forward(args)...); })) { - id_manager::on_init::func(static_cast(pair->second.get()), pair->second); - id_manager::on_stop::func(nullptr); - return pair->first.id(); + id_manager::on_init::func(static_cast(pair->second.get()), pair->second); + return pair->first; } - return id_manager::id_traits::invalid; + return id_manager::id_traits::invalid; } // Add a new ID for an existing object provided (returns new id) - template + template static inline u32 import_existing(const std::shared_ptr& ptr) { if (auto pair = create_id([&] { return ptr; })) { - id_manager::on_init::func(static_cast(pair->second.get()), pair->second); - id_manager::on_stop::func(nullptr); - return pair->first.id(); + id_manager::on_init::func(static_cast(pair->second.get()), pair->second); + return pair->first; } - return id_manager::id_traits::invalid; + return id_manager::id_traits::invalid; } // Add a new ID for an object returned by provider() - template> + template > static inline std::shared_ptr import(F&& provider) { if (auto pair = create_id(std::forward(provider))) { - id_manager::on_init::func(static_cast(pair->second.get()), pair->second); - id_manager::on_stop::func(nullptr); - return { pair->second, static_cast(pair->second.get()) }; + id_manager::on_init::func(static_cast(pair->second.get()), pair->second); + return {pair->second, static_cast(pair->second.get())}; } return nullptr; } // Check the ID - template + template static inline explicit_bool_t check(u32 id) { reader_lock lock(id_manager::g_mutex); - return find_id(get_type(), get_type(), id) != nullptr; + return find_id(id) != nullptr; } // Check the ID, access object under shared lock - template, typename = std::enable_if_t::value>> + template , typename = std::enable_if_t::value>> static inline explicit_bool_t check(u32 id, F&& func, int = 0) { reader_lock lock(id_manager::g_mutex); - const auto found = find_id(get_type(), get_type(), id); + const auto found = find_id(id); if (UNLIKELY(found == nullptr)) { @@ -373,12 +403,12 @@ public: } // Check the ID, access object under reader lock, propagate return value - template, typename = std::enable_if_t::value>> + template , typename = std::enable_if_t::value>> static inline return_pair check(u32 id, F&& func) { reader_lock lock(id_manager::g_mutex); - const auto found = find_id(get_type(), get_type(), id); + const auto found = find_id(id); if (UNLIKELY(found == nullptr)) { @@ -389,30 +419,30 @@ public: } // Get the object - template::value, T, Get>> - static inline std::shared_ptr get(u32 id) + template + static inline std::shared_ptr get(u32 id) { reader_lock lock(id_manager::g_mutex); - const auto found = find_id(get_type(), get_type(), id); + const auto found = find_id(id); if (UNLIKELY(found == nullptr)) { return nullptr; } - return {found->second, static_cast(found->second.get())}; + return {found->second, static_cast(found->second.get())}; } // Get the object, access object under reader lock - template, typename = std::enable_if_t::value>> + template , typename = std::enable_if_t::value>> static inline auto get(u32 id, F&& func, int = 0) { using result_type = std::shared_ptr; reader_lock lock(id_manager::g_mutex); - const auto found = find_id(get_type(), get_type(), id); + const auto found = find_id(id); if (UNLIKELY(found == nullptr)) { @@ -427,14 +457,14 @@ public: } // Get the object, access object under reader lock, propagate return value - template, typename = std::enable_if_t::value>> + template , typename = std::enable_if_t::value>> static inline auto get(u32 id, F&& func) { using result_type = return_pair; reader_lock lock(id_manager::g_mutex); - const auto found = find_id(get_type(), get_type(), id); + const auto found = find_id(id); if (UNLIKELY(found == nullptr)) { @@ -446,42 +476,52 @@ public: return result_type{{found->second, ptr}, func(*ptr)}; } - // Access all objects of specified types under reader lock (use lambda or callable object), return the number of objects processed - template::operator()), typename FRT = typename function_traits::void_type> + // Access all objects of specified type. Returns the number of objects processed. + template ::operator()), typename FRT = typename function_traits::void_type> static inline u32 select(F&& func, int = 0) { + static_assert(id_manager::id_verify::value, "Invalid ID type combination"); + reader_lock lock(id_manager::g_mutex); u32 result = 0; - for (u32 type : { get_type()... }) + for (auto& id : g_map[get_type()]) { - for (auto& id : g_map[type]) + if (id.second) { - func(id.first.id(), *static_cast::object_type*>(id.second.get())); - result++; + if (std::is_same::value || id.first.type() == get_type()) + { + func(id.first, *static_cast::object_type*>(id.second.get())); + result++; + } } - } + } return result; } - // Access all objects of specified types under reader lock (use lambda or callable object), if return value evaluates to true, stop and return the object and the value - template::operator()), typename FRT = typename function_traits::result_type> + // Access all objects of specified type. If function result evaluates to true, stop and return the object and the value. + template ::operator()), typename FRT = typename function_traits::result_type> static inline auto select(F&& func) { + static_assert(id_manager::id_verify::value, "Invalid ID type combination"); + using object_type = typename function_traits::object_type; using result_type = return_pair; reader_lock lock(id_manager::g_mutex); - for (u32 type : { get_type()... }) + for (auto& id : g_map[get_type()]) { - for (auto& id : g_map[type]) + if (auto ptr = static_cast(id.second.get())) { - if (FRT result = func(id.first.id(), *static_cast(id.second.get()))) + if (std::is_same::value || id.first.type() == get_type()) { - return result_type{{id.second, static_cast(id.second.get())}, std::move(result)}; + if (FRT result = func(id.first, *ptr)) + { + return result_type{{id.second, ptr}, std::move(result)}; + } } } } @@ -489,58 +529,52 @@ public: return result_type{nullptr}; } - // Get count of objects - template - static inline u32 get_count() + // Remove the ID + template + static inline explicit_bool_t remove(u32 id) { - reader_lock lock(id_manager::g_mutex); - - if (std::is_void::value) + std::shared_ptr ptr; { - return ::size32(g_map[get_type()]); - } + writer_lock lock(id_manager::g_mutex); - u32 result = 0; - - for (auto& id : g_map[get_type()]) - { - if (id.first.type() == get_type()) + if (const auto found = find_id(id)) { - result++; + ptr = std::move(found->second); + } + else + { + return false; } } - return result; - } - - // Remove the ID - template - static inline explicit_bool_t remove(u32 id) - { - if (auto ptr = (writer_lock{id_manager::g_mutex}, delete_id(get_type(), get_type(), id))) - { - id_manager::on_stop::func(static_cast(ptr.get())); - return true; - } - - return false; + id_manager::on_stop::func(static_cast(ptr.get())); + return true; } // Remove the ID and return the object - template + template static inline std::shared_ptr withdraw(u32 id) { - if (auto ptr = (writer_lock{id_manager::g_mutex}, delete_id(get_type(), get_type(), id))) + std::shared_ptr ptr; { - id_manager::on_stop::func(static_cast(ptr.get())); - return {ptr, static_cast(ptr.get())}; + writer_lock lock(id_manager::g_mutex); + + if (const auto found = find_id(id)) + { + ptr = std::move(found->second); + } + else + { + return nullptr; + } } - return nullptr; + id_manager::on_stop::func(static_cast(ptr.get())); + return {ptr, static_cast(ptr.get())}; } // Remove the ID after accessing the object under writer lock, return the object and propagate return value - template, typename = std::enable_if_t::value>> + template , typename = std::enable_if_t::value>> static inline auto withdraw(u32 id, F&& func, int = 0) { using result_type = std::shared_ptr; @@ -549,25 +583,24 @@ public: { writer_lock lock(id_manager::g_mutex); - const auto found = find_id(get_type(), get_type(), id); + if (const auto found = find_id(id)) + { + func(*static_cast(found->second.get())); - if (UNLIKELY(found == nullptr)) + ptr = std::move(found->second); + } + else { return result_type{nullptr}; } - - func(*static_cast(found->second.get())); - - ptr = delete_id(get_type(), get_type(), id); } - id_manager::on_stop::func(static_cast(ptr.get())); - + id_manager::on_stop::func(static_cast(ptr.get())); return result_type{ptr, static_cast(ptr.get())}; } // Conditionally remove the ID (if return value evaluates to false) after accessing the object under writer lock, return the object and propagate return value - template, typename = std::enable_if_t::value>> + template , typename = std::enable_if_t::value>> static inline auto withdraw(u32 id, F&& func) { using result_type = return_pair; @@ -577,27 +610,26 @@ public: { writer_lock lock(id_manager::g_mutex); - const auto found = find_id(get_type(), get_type(), id); + if (const auto found = find_id(id)) + { + const auto _ptr = static_cast(found->second.get()); - if (UNLIKELY(found == nullptr)) + ret = func(*_ptr); + + if (ret) + { + return result_type{{found->second, _ptr}, std::move(ret)}; + } + + ptr = std::move(found->second); + } + else { return result_type{nullptr}; } - - const auto _ptr = static_cast(found->second.get()); - - ret = func(*_ptr); - - if (ret) - { - return result_type{{found->second, _ptr}, std::move(ret)}; - } - - ptr = delete_id(get_type(), get_type(), id); } - - id_manager::on_stop::func(static_cast(ptr.get())); + id_manager::on_stop::func(static_cast(ptr.get())); return result_type{{ptr, static_cast(ptr.get())}, std::move(ret)}; } }; @@ -606,9 +638,9 @@ public: class fxm { // Type Index -> Object. Use global since only one process is supported atm. - static std::vector> g_vec; + static std::vector>> g_vec; - template + template static inline u32 get_type() { return id_manager::typeinfo::get_index(); @@ -622,47 +654,48 @@ public: static void clear(); // Create the object (returns nullptr if it already exists) - template + template static std::enable_if_t::value, std::shared_ptr> make(Args&&... args) { - id_manager::typeinfo::update(); - std::shared_ptr ptr; { writer_lock lock(id_manager::g_mutex); - if (!g_vec[get_type()]) + auto& pair = g_vec[get_type()]; + + if (!pair.second) { ptr = std::make_shared(std::forward(args)...); - g_vec[get_type()] = ptr; + pair.first = id_manager::typeinfo::get_stop(); + pair.second = ptr; + } + else + { + return nullptr; } } - if (ptr) - { - id_manager::on_init::func(ptr.get(), ptr); - id_manager::on_stop::func(nullptr); - } - + id_manager::on_init::func(ptr.get(), ptr); return ptr; } // Create the object unconditionally (old object will be removed if it exists) - template + template static std::enable_if_t::value, std::shared_ptr> make_always(Args&&... args) { - id_manager::typeinfo::update(); - std::shared_ptr ptr; std::shared_ptr old; { writer_lock lock(id_manager::g_mutex); - old = std::move(g_vec[get_type()]); - ptr = std::make_shared(std::forward(args)...); + auto& pair = g_vec[get_type()]; - g_vec[get_type()] = ptr; + ptr = std::make_shared(std::forward(args)...); + old = std::move(pair.second); + + pair.first = id_manager::typeinfo::get_stop(); + pair.second = ptr; } if (old) @@ -675,47 +708,48 @@ public: } // Emplace the object returned by provider() and return it if no object exists - template + template static auto import(F&& provider) -> decltype(static_cast>(provider())) { - id_manager::typeinfo::update(); - std::shared_ptr ptr; { writer_lock lock(id_manager::g_mutex); - if (!g_vec[get_type()]) + auto& pair = g_vec[get_type()]; + + if (!pair.second) { ptr = provider(); - g_vec[get_type()] = ptr; + pair.first = id_manager::typeinfo::get_stop(); + pair.second = ptr; + } + else + { + return nullptr; } } - if (ptr) - { - id_manager::on_init::func(ptr.get(), ptr); - id_manager::on_stop::func(nullptr); - } - + id_manager::on_init::func(ptr.get(), ptr); return ptr; } // Emplace the object return by provider() (old object will be removed if it exists) - template + template static auto import_always(F&& provider) -> decltype(static_cast>(provider())) { - id_manager::typeinfo::update(); - std::shared_ptr ptr; std::shared_ptr old; { writer_lock lock(id_manager::g_mutex); - old = std::move(g_vec[get_type()]); - ptr = provider(); + auto& pair = g_vec[get_type()]; - g_vec[get_type()] = ptr; + ptr = provider(); + old = std::move(pair.second); + + pair.first = id_manager::typeinfo::get_stop(); + pair.second = ptr; } if (old) @@ -728,62 +762,62 @@ public: } // Get the object unconditionally (create an object if it doesn't exist) - template + template static std::enable_if_t::value, std::shared_ptr> get_always(Args&&... args) { - id_manager::typeinfo::update(); - std::shared_ptr ptr; { writer_lock lock(id_manager::g_mutex); - if (auto& value = g_vec[get_type()]) + auto& pair = g_vec[get_type()]; + + if (auto& old = pair.second) { - return{ value, static_cast(value.get()) }; + return {old, static_cast(old.get())}; } else { ptr = std::make_shared(std::forward(args)...); - g_vec[get_type()] = ptr; + pair.first = id_manager::typeinfo::get_stop(); + pair.second = ptr; } } id_manager::on_init::func(ptr.get(), ptr); - id_manager::on_stop::func(nullptr); return ptr; } // Check whether the object exists - template + template static inline explicit_bool_t check() { reader_lock lock(id_manager::g_mutex); - return g_vec[get_type()].operator bool(); + return g_vec[get_type()].second != nullptr; } // Get the object (returns nullptr if it doesn't exist) - template + template static inline std::shared_ptr get() { reader_lock lock(id_manager::g_mutex); - auto& ptr = g_vec[get_type()]; + auto& ptr = g_vec[get_type()].second; - return{ ptr, static_cast(ptr.get()) }; + return {ptr, static_cast(ptr.get())}; } // Delete the object - template + template static inline explicit_bool_t remove() { std::shared_ptr ptr; { writer_lock lock(id_manager::g_mutex); - ptr = std::move(g_vec[get_type()]); + ptr = std::move(g_vec[get_type()].second); } - + if (ptr) { id_manager::on_stop::func(static_cast(ptr.get())); @@ -793,20 +827,20 @@ public: } // Delete the object and return it - template + template static inline std::shared_ptr withdraw() { std::shared_ptr ptr; { writer_lock lock(id_manager::g_mutex); - ptr = std::move(g_vec[get_type()]); + ptr = std::move(g_vec[get_type()].second); } if (ptr) { id_manager::on_stop::func(static_cast(ptr.get())); } - - return{ ptr, static_cast(ptr.get()) }; + + return {ptr, static_cast(ptr.get())}; } }; diff --git a/rpcs3/Emu/PSP2/ARMv7Thread.h b/rpcs3/Emu/PSP2/ARMv7Thread.h index 05e5f20f7d..1347bf7833 100644 --- a/rpcs3/Emu/PSP2/ARMv7Thread.h +++ b/rpcs3/Emu/PSP2/ARMv7Thread.h @@ -16,7 +16,7 @@ class ARMv7Thread final : public cpu_thread public: static const u32 id_base = 1; static const u32 id_step = 2; - static const u32 id_count = 32767; + static const u32 id_count = 4096; virtual std::string get_name() const override; virtual std::string dump() const override; diff --git a/rpcs3/Emu/PSP2/Modules/sceLibKernel.cpp b/rpcs3/Emu/PSP2/Modules/sceLibKernel.cpp index fa3cfe037e..54596f7014 100644 --- a/rpcs3/Emu/PSP2/Modules/sceLibKernel.cpp +++ b/rpcs3/Emu/PSP2/Modules/sceLibKernel.cpp @@ -809,8 +809,8 @@ s32 sceKernelWaitMultipleEventsCB(vm::ptr pWaitEventList, s3 struct psp2_event_flag final { static const u32 id_base = 1; - static const u32 id_step = 1; - static const u32 id_count = 32767; + static const u32 id_step = 2; + static const u32 id_count = 8192; using ipc = ipc_manager; diff --git a/rpcs3/Emu/PSP2/Modules/sceLibKernel.h b/rpcs3/Emu/PSP2/Modules/sceLibKernel.h index 7300016e90..cb025be4bf 100644 --- a/rpcs3/Emu/PSP2/Modules/sceLibKernel.h +++ b/rpcs3/Emu/PSP2/Modules/sceLibKernel.h @@ -497,8 +497,8 @@ struct SceKernelSemaInfo struct psp2_semaphore { static const u32 id_base = 1; - static const u32 id_step = 1; - static const u32 id_count = 32767; + static const u32 id_step = 2; + static const u32 id_count = 8192; const std::string name; // IPC Name @@ -541,8 +541,8 @@ struct SceKernelMutexInfo struct psp2_mutex { static const u32 id_base = 1; - static const u32 id_step = 1; - static const u32 id_count = 32767; + static const u32 id_step = 2; + static const u32 id_count = 8192; const std::string name; // IPC Name @@ -605,8 +605,8 @@ struct SceKernelCondInfo struct psp2_cond { static const u32 id_base = 1; - static const u32 id_step = 1; - static const u32 id_count = 32767; + static const u32 id_step = 2; + static const u32 id_count = 8192; const std::string name; // IPC Name diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 9a3de8db84..b9d0f25f03 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -49,7 +49,7 @@ extern u64 get_system_time(); extern void ppu_load_exec(const ppu_exec_object&); extern void spu_load_exec(const spu_exec_object&); extern void arm_load_exec(const arm_exec_object&); -extern std::shared_ptr ppu_load_prx(const ppu_prx_object&); +extern std::shared_ptr ppu_load_prx(const ppu_prx_object&); fs::file g_tty; @@ -346,10 +346,15 @@ void Emulator::Run() m_pause_amend_time = 0; m_status = Running; - idm::select([](u32, cpu_thread& cpu) + auto on_select = [](u32, cpu_thread& cpu) { cpu.run(); - }); + }; + + idm::select(on_select); + idm::select(on_select); + idm::select(on_select); + idm::select(on_select); SendDbgCommand(DID_STARTED_EMU); } @@ -374,10 +379,15 @@ bool Emulator::Pause() SendDbgCommand(DID_PAUSE_EMU); - idm::select([](u32, cpu_thread& cpu) + auto on_select = [](u32, cpu_thread& cpu) { cpu.state += cpu_flag::dbg_global_pause; - }); + }; + + idm::select(on_select); + idm::select(on_select); + idm::select(on_select); + idm::select(on_select); SendDbgCommand(DID_PAUSED_EMU); @@ -411,11 +421,16 @@ void Emulator::Resume() { LV2_LOCK; - idm::select([](u32, cpu_thread& cpu) + auto on_select = [](u32, cpu_thread& cpu) { cpu.state -= cpu_flag::dbg_global_pause; cpu.notify(); - }); + }; + + idm::select(on_select); + idm::select(on_select); + idm::select(on_select); + idm::select(on_select); } rpcs3::on_resume()(); @@ -438,12 +453,16 @@ void Emulator::Stop() { LV2_LOCK; - idm::select([](u32, cpu_thread& cpu) + auto on_select = [](u32, cpu_thread& cpu) { cpu.state += cpu_flag::dbg_global_stop; cpu.get()->set_exception(std::make_exception_ptr(EmulationStopped())); - cpu.notify(); - }); + }; + + idm::select(on_select); + idm::select(on_select); + idm::select(on_select); + idm::select(on_select); } LOG_NOTICE(GENERAL, "All threads signaled..."); diff --git a/rpcs3/Gui/InterpreterDisAsm.cpp b/rpcs3/Gui/InterpreterDisAsm.cpp index d1ad3126de..f49b15f8ae 100644 --- a/rpcs3/Gui/InterpreterDisAsm.cpp +++ b/rpcs3/Gui/InterpreterDisAsm.cpp @@ -122,10 +122,15 @@ void InterpreterDisAsmFrame::UpdateUnitList() m_choice_units->Freeze(); m_choice_units->Clear(); - idm::select([&](u32, cpu_thread& cpu) + const auto on_select = [&](u32, cpu_thread& cpu) { m_choice_units->Append(cpu.get_name(), &cpu); - }); + }; + + idm::select(on_select); + idm::select(on_select); + idm::select(on_select); + idm::select(on_select); m_choice_units->Thaw(); } diff --git a/rpcs3/Gui/KernelExplorer.cpp b/rpcs3/Gui/KernelExplorer.cpp index 634546b9d8..765bc688b1 100644 --- a/rpcs3/Gui/KernelExplorer.cpp +++ b/rpcs3/Gui/KernelExplorer.cpp @@ -19,6 +19,10 @@ #include "Emu/Cell/lv2/sys_memory.h" #include "Emu/Cell/lv2/sys_mmapper.h" #include "Emu/Cell/lv2/sys_spu.h" +#include "Emu/Cell/lv2/sys_interrupt.h" +#include "Emu/Cell/lv2/sys_timer.h" +#include "Emu/Cell/lv2/sys_process.h" +#include "Emu/Cell/lv2/sys_fs.h" #include "KernelExplorer.h" @@ -57,7 +61,15 @@ KernelExplorer::KernelExplorer(wxWindow* parent) void KernelExplorer::Update() { m_tree->DeleteAllItems(); - const u32 total_memory_usage = vm::get(vm::user_space)->used(); + + const auto vm_block = vm::get(vm::user_space); + + if (!vm_block) + { + return; + } + + const u32 total_memory_usage = vm_block->used(); const auto& root = m_tree->AddRoot(fmt::format("Process, ID = 0x00000001, Total Memory Usage = 0x%x (%0.2f MB)", total_memory_usage, (float)total_memory_usage / (1024 * 1024))); @@ -67,11 +79,11 @@ void KernelExplorer::Update() char string[8]; name64(u64 data) - : u64_data(data & 0x00ffffffffffffffull) + : u64_data(data & 0x00ffffffffffffffull) { } - const char* operator &() const + const char* operator+() const { return string; } @@ -79,167 +91,203 @@ void KernelExplorer::Update() // TODO: FileSystem - // Semaphores - if (const u32 count = idm::get_count()) + struct lv2_obj_rec { - const auto& node = m_tree->AppendItem(root, fmt::format("Semaphores (%zu)", count)); + wxTreeItemId node; + u32 count{0}; - idm::select([&](u32 id, lv2_sema_t& sema) + lv2_obj_rec() = default; + lv2_obj_rec(wxTreeItemId node) + : node(node) { - m_tree->AppendItem(node, fmt::format("Semaphore: ID = 0x%08x '%s', Count = %d, Max Count = %d, Waiters = %#zu", id, - &name64(sema.name), sema.value.load(), sema.max, sema.sq.size())); - }); - } + } + }; - // Mutexes - if (const u32 count = idm::get_count()) + std::vector lv2_types(256); + lv2_types[SYS_MEM_OBJECT] = m_tree->AppendItem(root, "Memory"); + lv2_types[SYS_MUTEX_OBJECT] = m_tree->AppendItem(root, "Mutexes"); + lv2_types[SYS_COND_OBJECT] = m_tree->AppendItem(root, "Condition Variables"); + lv2_types[SYS_RWLOCK_OBJECT] = m_tree->AppendItem(root, "Reader Writer Locks"); + lv2_types[SYS_INTR_TAG_OBJECT] = m_tree->AppendItem(root, "Interrupt Tags"); + lv2_types[SYS_INTR_SERVICE_HANDLE_OBJECT] = m_tree->AppendItem(root, "Interrupt Service Handles"); + lv2_types[SYS_EVENT_QUEUE_OBJECT] = m_tree->AppendItem(root, "Event Queues"); + lv2_types[SYS_EVENT_PORT_OBJECT] = m_tree->AppendItem(root, "Event Ports"); + lv2_types[SYS_TRACE_OBJECT] = m_tree->AppendItem(root, "Traces"); + lv2_types[SYS_SPUIMAGE_OBJECT] = m_tree->AppendItem(root, "SPU Images"); + lv2_types[SYS_PRX_OBJECT] = m_tree->AppendItem(root, "Modules"); + lv2_types[SYS_SPUPORT_OBJECT] = m_tree->AppendItem(root, "SPU Ports"); + lv2_types[SYS_LWMUTEX_OBJECT] = m_tree->AppendItem(root, "Light Weight Mutexes"); + lv2_types[SYS_TIMER_OBJECT] = m_tree->AppendItem(root, "Timers"); + lv2_types[SYS_SEMAPHORE_OBJECT] = m_tree->AppendItem(root, "Semaphores"); + lv2_types[SYS_LWCOND_OBJECT] = m_tree->AppendItem(root, "Light Weight Condition Variables"); + lv2_types[SYS_EVENT_FLAG_OBJECT] = m_tree->AppendItem(root, "Event Flags"); + + idm::select([&](u32 id, lv2_obj& obj) { - const auto& node = m_tree->AppendItem(root, fmt::format("Mutexes (%zu)", count)); + lv2_types[id >> 24].count++; - idm::select([&](u32 id, lv2_mutex_t& mutex) + if (auto& node = lv2_types[id >> 24].node) switch (id >> 24) { - m_tree->AppendItem(node, fmt::format("Mutex: ID = 0x%08x '%s'", id, - &name64(mutex.name))); - }); - } - - // Lightweight Mutexes - if (const u32 count = idm::get_count()) - { - const auto& node = m_tree->AppendItem(root, fmt::format("Lightweight Mutexes (%zu)", count)); - - idm::select([&](u32 id, lv2_lwmutex_t& lwm) + case SYS_MEM_OBJECT: { - m_tree->AppendItem(node, fmt::format("LWMutex: ID = 0x%08x '%s'", id, - &name64(lwm.name))); - }); - } - - // Condition Variables - if (const u32 count = idm::get_count()) - { - const auto& node = m_tree->AppendItem(root, fmt::format("Condition Variables (%zu)", count)); - - idm::select([&](u32 id, lv2_cond_t& cond) + auto& mem = static_cast(obj); + m_tree->AppendItem(node, fmt::format("Memory: ID = 0x%08x", id)); + break; + } + case SYS_MUTEX_OBJECT: { - m_tree->AppendItem(node, fmt::format("Cond: ID = 0x%08x '%s'", id, - &name64(cond.name))); - }); - } - - // Lightweight Condition Variables - if (const u32 count = idm::get_count()) - { - const auto& node = m_tree->AppendItem(root, fmt::format("Lightweight Condition Variables (%zu)", count)); - - idm::select([&](u32 id, lv2_lwcond_t& lwc) + auto& mutex = static_cast(obj); + m_tree->AppendItem(node, fmt::format("Mutex: ID = 0x%08x \"%s\"", id, +name64(mutex.name))); + break; + } + case SYS_COND_OBJECT: { - m_tree->AppendItem(node, fmt::format("LWCond: ID = 0x%08x '%s'", id, - &name64(lwc.name))); - }); - } - - // Event Queues - if (const u32 count = idm::get_count()) - { - const auto& node = m_tree->AppendItem(root, fmt::format("Event Queues (%zu)", count)); - - idm::select([&](u32 id, lv2_event_queue_t& eq) + auto& cond = static_cast(obj); + m_tree->AppendItem(node, fmt::format("Cond: ID = 0x%08x \"%s\"", id, +name64(cond.name))); + break; + } + case SYS_RWLOCK_OBJECT: { - m_tree->AppendItem(node, fmt::format("Event Queue: ID = 0x%08x '%s', %s, Key = %#llx, Events = %zu/%d, Waiters = %zu", id, - &name64(eq.name), eq.type == SYS_SPU_QUEUE ? "SPU" : "PPU", eq.ipc_key, eq.events(), eq.size, eq.waiters())); - }); - } - - // Event Ports - if (const u32 count = idm::get_count()) - { - const auto& node = m_tree->AppendItem(root, fmt::format("Event Ports (%zu)", count)); - - idm::select([&](u32 id, lv2_event_port_t& ep) + auto& rw = static_cast(obj); + m_tree->AppendItem(node, fmt::format("RW Lock: ID = 0x%08x", id)); + break; + } + case SYS_INTR_TAG_OBJECT: { - m_tree->AppendItem(node, fmt::format("Event Port: ID = 0x%08x, Name = %#llx", id, - ep.name)); - }); - } - - // Event Flags - if (const u32 count = idm::get_count()) - { - const auto& node = m_tree->AppendItem(root, fmt::format("Event Flags (%zu)", count)); - - idm::select([&](u32 id, lv2_event_flag_t& ef) + auto& tag = static_cast(obj); + m_tree->AppendItem(node, fmt::format("Intr Tag: ID = 0x%08x", id)); + break; + } + case SYS_INTR_SERVICE_HANDLE_OBJECT: { - m_tree->AppendItem(node, fmt::format("Event Flag: ID = 0x%08x '%s', Type = 0x%x, Pattern = 0x%llx", id, - &name64(ef.name), ef.type, ef.pattern.load())); - }); - } - - // Reader/writer Locks - if (const u32 count = idm::get_count()) - { - const auto& node = m_tree->AppendItem(root, fmt::format("Reader/writer Locks (%zu)", count)); - - idm::select([&](u32 id, lv2_rwlock_t&) + auto& serv = static_cast(obj); + m_tree->AppendItem(node, fmt::format("Intr Svc: ID = 0x%08x", id)); + break; + } + case SYS_EVENT_QUEUE_OBJECT: { - m_tree->AppendItem(node, fmt::format("RWLock: ID = 0x%08x", id)); - }); - } - - // PRX Libraries - if (const u32 count = idm::get_count()) - { - const auto& node = m_tree->AppendItem(root, fmt::format("PRX Libraries (%zu)", count)); - - idm::select([&](u32 id, lv2_prx_t&) + auto& eq = static_cast(obj); + m_tree->AppendItem(node, fmt::format("Event Queue: ID = 0x%08x \"%s\", %s, Key = %#llx, Events = %zu/%d, Waiters = %zu", id, +name64(eq.name), + eq.type == SYS_SPU_QUEUE ? "SPU" : "PPU", eq.ipc_key, eq.events(), eq.size, eq.waiters())); + break; + } + case SYS_EVENT_PORT_OBJECT: { + auto& ep = static_cast(obj); + m_tree->AppendItem(node, fmt::format("Event Port: ID = 0x%08x, Name = %#llx", id, ep.name)); + break; + } + case SYS_TRACE_OBJECT: + { + m_tree->AppendItem(node, fmt::format("Trace: ID = 0x%08x", id)); + break; + } + case SYS_SPUIMAGE_OBJECT: + { + m_tree->AppendItem(node, fmt::format("SPU Image: ID = 0x%08x", id)); + break; + } + case SYS_PRX_OBJECT: + { + auto& prx = static_cast(obj); m_tree->AppendItem(node, fmt::format("PRX: ID = 0x%08x", id)); - }); - } - - // Memory Containers - if (const u32 count = idm::get_count()) - { - const auto& node = m_tree->AppendItem(root, fmt::format("Memory Containers (%zu)", count)); - - idm::select([&](u32 id, lv2_memory_container&) + break; + } + case SYS_SPUPORT_OBJECT: { - m_tree->AppendItem(node, fmt::format("Memory Container: ID = 0x%08x", id)); - }); - } - - // Memory Objects - if (const u32 count = idm::get_count()) - { - const auto& node = m_tree->AppendItem(root, fmt::format("Memory Objects (%zu)", count)); - - idm::select([&](u32 id, lv2_memory&) + m_tree->AppendItem(node, fmt::format("SPU Port: ID = 0x%08x", id)); + break; + } + case SYS_LWMUTEX_OBJECT: { - m_tree->AppendItem(node, fmt::format("Memory Object: ID = 0x%08x", id)); - }); - } - - // PPU Threads - if (const u32 count = idm::get_count()) - { - const auto& node = m_tree->AppendItem(root, fmt::format("PPU Threads (%zu)", count)); - - idm::select([&](u32 id, ppu_thread& ppu) + auto& lwm = static_cast(obj); + m_tree->AppendItem(node, fmt::format("LWMutex: ID = 0x%08x \"%s\"", id, +name64(lwm.name))); + break; + } + case SYS_TIMER_OBJECT: { - m_tree->AppendItem(node, fmt::format("PPU Thread: ID = 0x%08x '%s'", id, ppu.get_name())); - }); - } - - // SPU Thread Groups - if (const u32 count = idm::get_count()) - { - const auto& node = m_tree->AppendItem(root, fmt::format("SPU Thread Groups (%d)", count)); - - idm::select([&](u32 id, lv2_spu_group_t& tg) + auto& timer = static_cast(obj); + m_tree->AppendItem(node, fmt::format("Timer: ID = 0x%08x", id)); + break; + } + case SYS_SEMAPHORE_OBJECT: { - m_tree->AppendItem(node, fmt::format("SPU Thread Group: ID = 0x%08x '%s'", id, - tg.name.c_str())); - }); + auto& sema = static_cast(obj); + m_tree->AppendItem(node, fmt::format("Semaphore: ID = 0x%08x \"%s\", Count = %d, Max Count = %d, Waiters = %#zu", id, +name64(sema.name), + sema.value.load(), sema.max, sema.sq.size())); + break; + } + case SYS_LWCOND_OBJECT: + { + auto& lwc = static_cast(obj); + m_tree->AppendItem(node, fmt::format("LWCond: ID = 0x%08x \"%s\"", id, +name64(lwc.name))); + break; + } + case SYS_EVENT_FLAG_OBJECT: + { + auto& ef = static_cast(obj); + m_tree->AppendItem(node, fmt::format("Event Flag: ID = 0x%08x \"%s\", Type = 0x%x, Pattern = 0x%llx", id, +name64(ef.name), ef.type, ef.pattern.load())); + break; + } + default: + { + m_tree->AppendItem(node, fmt::format("Unknown object: ID = 0x%08x", id)); + } + } + }); + + lv2_types.emplace_back(m_tree->AppendItem(root, "Memory Containers")); + + idm::select([&](u32 id, lv2_memory_container&) + { + lv2_types.back().count++; + m_tree->AppendItem(lv2_types.back().node, fmt::format("Memory Container: ID = 0x%08x", id)); + }); + + lv2_types.emplace_back(m_tree->AppendItem(root, "PPU Threads")); + + idm::select([&](u32 id, ppu_thread& ppu) + { + lv2_types.back().count++; + m_tree->AppendItem(lv2_types.back().node, fmt::format("PPU Thread: ID = 0x%08x '%s'", id, ppu.get_name())); + }); + + lv2_types.emplace_back(m_tree->AppendItem(root, "SPU Threads")); + + idm::select([&](u32 id, SPUThread& spu) + { + lv2_types.back().count++; + m_tree->AppendItem(lv2_types.back().node, fmt::format("SPU Thread: ID = 0x%08x '%s'", id, spu.get_name())); + }); + + lv2_types.emplace_back(m_tree->AppendItem(root, "SPU Thread Groups")); + + idm::select([&](u32 id, lv2_spu_group& tg) + { + lv2_types.back().count++; + m_tree->AppendItem(lv2_types.back().node, fmt::format("SPU Thread Group: ID = 0x%08x '%s'", id, tg.name.c_str())); + }); + + lv2_types.emplace_back(m_tree->AppendItem(root, "File Descriptors")); + + idm::select([&](u32 id, lv2_fs_object& fo) + { + lv2_types.back().count++; + m_tree->AppendItem(lv2_types.back().node, fmt::format("FD: ID = 0x%08x '%s'", id)); + }); + + for (auto&& entry : lv2_types) + { + if (entry.node && entry.count) + { + // Append object count + m_tree->SetItemText(entry.node, m_tree->GetItemText(entry.node) + fmt::format(" (%zu)", entry.count)); + } + else if (entry.node) + { + // Delete node otherwise + m_tree->Delete(entry.node); + } } // RawSPU Threads (TODO)