diff --git a/rpcs3/Emu/Cell/Modules/cellAdec.cpp b/rpcs3/Emu/Cell/Modules/cellAdec.cpp index dc241932fe..24d26a2ad5 100644 --- a/rpcs3/Emu/Cell/Modules/cellAdec.cpp +++ b/rpcs3/Emu/Cell/Modules/cellAdec.cpp @@ -558,9 +558,9 @@ s32 cellAdecOpen(vm::ptr type, vm::ptr res, vm:: return CELL_ADEC_ERROR_ARG; } - auto&& adec = std::make_shared(type->audioCodecType, res->startAddr, res->totalMemSize, cb->cbFunc, cb->cbArg); + auto&& adec = idm::make_ptr(type->audioCodecType, res->startAddr, res->totalMemSize, cb->cbFunc, cb->cbArg); - *handle = idm::import_existing(adec); + *handle = adec->id; adec->run(); @@ -576,9 +576,9 @@ s32 cellAdecOpenEx(vm::ptr type, vm::ptr res, return CELL_ADEC_ERROR_ARG; } - auto&& adec = std::make_shared(type->audioCodecType, res->startAddr, res->totalMemSize, cb->cbFunc, cb->cbArg); + auto&& adec = idm::make_ptr(type->audioCodecType, res->startAddr, res->totalMemSize, cb->cbFunc, cb->cbArg); - *handle = idm::import_existing(adec); + *handle = adec->id; adec->run(); diff --git a/rpcs3/Emu/Cell/Modules/cellDmux.cpp b/rpcs3/Emu/Cell/Modules/cellDmux.cpp index e367af6b8a..6ec135e98c 100644 --- a/rpcs3/Emu/Cell/Modules/cellDmux.cpp +++ b/rpcs3/Emu/Cell/Modules/cellDmux.cpp @@ -976,9 +976,9 @@ s32 cellDmuxOpen(vm::cptr type, vm::cptr res, vm } // TODO: check demuxerResource and demuxerCb arguments - auto&& dmux = std::make_shared(res->memAddr, res->memSize, cb->cbMsgFunc, cb->cbArg); + auto&& dmux = idm::make_ptr(res->memAddr, res->memSize, cb->cbMsgFunc, cb->cbArg); - *handle = idm::import_existing(dmux); + *handle = dmux->id; dmux->run(); @@ -995,9 +995,9 @@ s32 cellDmuxOpenEx(vm::cptr type, vm::cptr res } // TODO: check demuxerResourceEx and demuxerCb arguments - auto&& dmux = std::make_shared(resEx->memAddr, resEx->memSize, cb->cbMsgFunc, cb->cbArg); + auto&& dmux = idm::make_ptr(resEx->memAddr, resEx->memSize, cb->cbMsgFunc, cb->cbArg); - *handle = idm::import_existing(dmux); + *handle = dmux->id; dmux->run(); @@ -1021,9 +1021,9 @@ s32 cellDmuxOpen2(vm::cptr type2, vm::cptr res } // TODO: check demuxerType2, demuxerResource2 and demuxerCb arguments - auto&& dmux = std::make_shared(res2->memAddr, res2->memSize, cb->cbMsgFunc, cb->cbArg); + auto&& dmux = idm::make_ptr(res2->memAddr, res2->memSize, cb->cbMsgFunc, cb->cbArg); - *handle = idm::import_existing(dmux); + *handle = dmux->id; dmux->run(); diff --git a/rpcs3/Emu/Cell/Modules/cellFs.cpp b/rpcs3/Emu/Cell/Modules/cellFs.cpp index 238c0ad06f..5d23b6dfec 100644 --- a/rpcs3/Emu/Cell/Modules/cellFs.cpp +++ b/rpcs3/Emu/Cell/Modules/cellFs.cpp @@ -737,12 +737,12 @@ struct fs_aio_thread : ppu_thread struct fs_aio_manager { - std::shared_ptr t = std::make_shared("FS AIO Thread", 500); + std::shared_ptr thread; fs_aio_manager() + : thread(idm::make_ptr("FS AIO Thread", 500)) { - idm::import_existing(t); - t->run(); + thread->run(); } }; @@ -779,13 +779,13 @@ s32 cellFsAioRead(vm::ptr aio, vm::ptr id, fs_aio_cb_t func) const auto m = fxm::get_always(); - m->t->cmd_list + m->thread->cmd_list ({ { 1, xid }, { aio, func }, }); - m->t->lock_notify(); + m->thread->lock_notify(); return CELL_OK; } @@ -800,13 +800,13 @@ s32 cellFsAioWrite(vm::ptr aio, vm::ptr id, fs_aio_cb_t func) const auto m = fxm::get_always(); - m->t->cmd_list + m->thread->cmd_list ({ { 2, xid }, { aio, func }, }); - m->t->lock_notify(); + m->thread->lock_notify(); return CELL_OK; } diff --git a/rpcs3/Emu/Cell/Modules/cellSpurs.cpp b/rpcs3/Emu/Cell/Modules/cellSpurs.cpp index a07623d74f..22a9d43540 100644 --- a/rpcs3/Emu/Cell/Modules/cellSpurs.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSpurs.cpp @@ -607,9 +607,9 @@ s32 _spurs::create_handler(vm::ptr spurs, u32 ppuPriority) } }; - auto&& eht = std::make_shared(std::string(spurs->prefix, spurs->prefixSize) + "SpursHdlr0", ppuPriority, 0x4000); + auto&& eht = idm::make_ptr(std::string(spurs->prefix, spurs->prefixSize) + "SpursHdlr0", ppuPriority, 0x4000); - spurs->ppu0 = idm::import_existing(eht); + spurs->ppu0 = eht->id; eht->gpr[3] = spurs.addr(); eht->run(); @@ -804,11 +804,9 @@ s32 _spurs::create_event_helper(ppu_thread& ppu, vm::ptr spurs, u32 p } }; - auto&& eht = std::make_shared(std::string(spurs->prefix, spurs->prefixSize) + "SpursHdlr1", ppuPriority, 0x8000); + auto&& eht = idm::make_ptr(std::string(spurs->prefix, spurs->prefixSize) + "SpursHdlr1", ppuPriority, 0x8000); - const u32 tid = idm::import_existing(eht); - - if (tid == 0) + if (!eht) { sys_event_port_disconnect(spurs->eventPort); sys_event_port_destroy(spurs->eventPort); @@ -825,7 +823,7 @@ s32 _spurs::create_event_helper(ppu_thread& ppu, vm::ptr spurs, u32 p eht->gpr[3] = spurs.addr(); eht->run(); - spurs->ppu1 = tid; + spurs->ppu1 = eht->id; return CELL_OK; } diff --git a/rpcs3/Emu/Cell/Modules/cellVdec.cpp b/rpcs3/Emu/Cell/Modules/cellVdec.cpp index 72132772e7..75986b2426 100644 --- a/rpcs3/Emu/Cell/Modules/cellVdec.cpp +++ b/rpcs3/Emu/Cell/Modules/cellVdec.cpp @@ -399,10 +399,10 @@ s32 cellVdecOpen(vm::cptr type, vm::cptr res, vm cellVdec.warning("cellVdecOpen(type=*0x%x, res=*0x%x, cb=*0x%x, handle=*0x%x)", type, res, cb, handle); // Create decoder thread - auto&& vdec = std::make_shared(type->codecType, type->profileLevel, res->memAddr, res->memSize, cb->cbFunc, cb->cbArg); + auto&& vdec = idm::make_ptr(type->codecType, type->profileLevel, res->memAddr, res->memSize, cb->cbFunc, cb->cbArg); // Hack: store thread id (normally it should be pointer) - *handle = idm::import_existing(vdec); + *handle = vdec->id; vdec->run(); @@ -414,10 +414,10 @@ s32 cellVdecOpenEx(vm::cptr type, vm::cptr r cellVdec.warning("cellVdecOpenEx(type=*0x%x, res=*0x%x, cb=*0x%x, handle=*0x%x)", type, res, cb, handle); // Create decoder thread - auto&& vdec = std::make_shared(type->codecType, type->profileLevel, res->memAddr, res->memSize, cb->cbFunc, cb->cbArg); + auto&& vdec = idm::make_ptr(type->codecType, type->profileLevel, res->memAddr, res->memSize, cb->cbFunc, cb->cbArg); // Hack: store thread id (normally it should be pointer) - *handle = idm::import_existing(vdec); + *handle = vdec->id; vdec->run(); @@ -428,7 +428,7 @@ s32 cellVdecClose(u32 handle) { cellVdec.warning("cellVdecClose(handle=0x%x)", handle); - const auto vdec = std::dynamic_pointer_cast(idm::get(handle)); // TODO: avoid RTTI + const auto vdec = idm::get(handle); if (!vdec) { @@ -446,7 +446,7 @@ s32 cellVdecStartSeq(u32 handle) { cellVdec.trace("cellVdecStartSeq(handle=0x%x)", handle); - const auto vdec = std::dynamic_pointer_cast(idm::get(handle)); // TODO: avoid RTTI + const auto vdec = idm::get(handle); if (!vdec) { @@ -462,7 +462,7 @@ s32 cellVdecEndSeq(u32 handle) { cellVdec.warning("cellVdecEndSeq(handle=0x%x)", handle); - const auto vdec = std::dynamic_pointer_cast(idm::get(handle)); // TODO: avoid RTTI + const auto vdec = idm::get(handle); if (!vdec) { @@ -478,7 +478,7 @@ s32 cellVdecDecodeAu(u32 handle, CellVdecDecodeMode mode, vm::cptr(idm::get(handle)); // TODO: avoid RTTI + const auto vdec = idm::get(handle); if (mode > CELL_VDEC_DEC_MODE_PB_SKIP || !vdec) { @@ -509,7 +509,7 @@ s32 cellVdecGetPicture(u32 handle, vm::cptr format, vm::ptr(idm::get(handle)); // TODO: avoid RTTI + const auto vdec = idm::get(handle); if (!format || !vdec) { @@ -629,7 +629,7 @@ s32 cellVdecGetPicItem(u32 handle, vm::pptr picItem) { cellVdec.trace("cellVdecGetPicItem(handle=0x%x, picItem=**0x%x)", handle, picItem); - const auto vdec = std::dynamic_pointer_cast(idm::get(handle)); // TODO: avoid RTTI + const auto vdec = idm::get(handle); if (!vdec) { @@ -824,7 +824,7 @@ s32 cellVdecSetFrameRate(u32 handle, CellVdecFrameRate frc) { cellVdec.trace("cellVdecSetFrameRate(handle=0x%x, frc=0x%x)", handle, frc); - const auto vdec = std::dynamic_pointer_cast(idm::get(handle)); // TODO: avoid RTTI + const auto vdec = idm::get(handle); if (!vdec) { diff --git a/rpcs3/Emu/Cell/Modules/libmixer.cpp b/rpcs3/Emu/Cell/Modules/libmixer.cpp index e129cfda2c..b9db1c6443 100644 --- a/rpcs3/Emu/Cell/Modules/libmixer.cpp +++ b/rpcs3/Emu/Cell/Modules/libmixer.cpp @@ -489,9 +489,7 @@ s32 cellSurMixerCreate(vm::cptr config) libmixer.warning("*** surMixer created (ch1=%d, ch2=%d, ch6=%d, ch8=%d)", config->chStrips1, config->chStrips2, config->chStrips6, config->chStrips8); - auto&& thread = std::make_shared("Surmixer Thread"); - - idm::import_existing(thread); + auto&& thread = idm::make_ptr("Surmixer Thread"); thread->run(); diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index 6a2889a221..8f3c909c44 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -80,6 +80,7 @@ std::string ppu_thread::dump() const { std::string ret; + ret += fmt::format("Type: %s\n", typeid(*this).name()); ret += fmt::format("State: 0x%08x\n", state.load()); ret += fmt::format("Priority: %d\n", prio); diff --git a/rpcs3/Emu/IdManager.cpp b/rpcs3/Emu/IdManager.cpp index 3c287716e3..ad6ae666ab 100644 --- a/rpcs3/Emu/IdManager.cpp +++ b/rpcs3/Emu/IdManager.cpp @@ -24,7 +24,7 @@ u32 id_manager::typeinfo::add_type() return ::size32(list) - 1; } -id_manager::id_map::pointer idm::allocate_id(u32 tag, u32 min, u32 max) +id_manager::id_map::pointer idm::allocate_id(u32 tag, u32 type, u32 min, u32 max) { // Check all IDs starting from "next id" for (u32 i = 0; i <= max - min; i++) @@ -33,7 +33,7 @@ id_manager::id_map::pointer idm::allocate_id(u32 tag, u32 min, u32 max) if (g_id[tag] < min || g_id[tag] > max) g_id[tag] = min; // Get ID - const auto r = g_map[tag].emplace(g_id[tag]++, nullptr); + const auto r = g_map[tag].emplace(id_manager::id_key{g_id[tag]++, type}, nullptr); if (r.second) { @@ -58,19 +58,23 @@ std::shared_ptr idm::deallocate_id(u32 tag, u32 id) return ptr; } -id_manager::id_map::pointer idm::find_id(u32 type, u32 id) +id_manager::id_map::pointer idm::find_id(u32 type, u32 true_type, u32 id) { const auto found = g_map[type].find(id); if (found == g_map[type].end()) return nullptr; + if (true_type != get_type() && found->first.type() != true_type) return nullptr; + return &*found; } -std::shared_ptr idm::delete_id(u32 type, u32 tag, u32 id) +std::shared_ptr idm::delete_id(u32 type, u32 true_type, u32 tag, u32 id) { writer_lock lock(g_mutex); + if (!find_id(type, true_type, id)) return nullptr; // ??? + auto&& ptr = deallocate_id(tag, id); g_map[type].erase(id); diff --git a/rpcs3/Emu/IdManager.h b/rpcs3/Emu/IdManager.h index 0a1eb22d21..1f0ad12ac5 100644 --- a/rpcs3/Emu/IdManager.h +++ b/rpcs3/Emu/IdManager.h @@ -228,13 +228,13 @@ class idm }; // Prepares new ID, returns nullptr if out of resources - static id_manager::id_map::pointer allocate_id(u32 tag, u32 min, u32 max); + static id_manager::id_map::pointer allocate_id(u32 tag, u32 type, u32 min, u32 max); // Deallocate ID, returns object static std::shared_ptr deallocate_id(u32 tag, u32 id); // Allocate new ID and construct it from the provider() - template + template static id_manager::id_map::pointer create_id(F&& provider) { id_manager::typeinfo::update(); @@ -242,7 +242,7 @@ class idm writer_lock lock(g_mutex); - if (auto place = allocate_id(get_tag(), id_manager::id_traits::min, id_manager::id_traits::max)) + if (auto place = allocate_id(get_tag(), get_type(), id_manager::id_traits::min, id_manager::id_traits::max)) { try { @@ -265,10 +265,10 @@ class idm } // Get ID (internal) - static id_manager::id_map::pointer find_id(u32 type, u32 id); + static id_manager::id_map::pointer find_id(u32 type, u32 true_type, u32 id); // Remove ID and return object - static std::shared_ptr delete_id(u32 type, u32 tag, u32 id); + static std::shared_ptr delete_id(u32 type, u32 true_type, u32 tag, u32 id); public: // Initialize object manager @@ -279,13 +279,13 @@ public: // Add a new ID of specified type with specified constructor arguments (returns object or nullptr) template - static inline std::enable_if_t::value, std::shared_ptr> make_ptr(Args&&... args) + static inline std::enable_if_t::value, std::shared_ptr> make_ptr(Args&&... args) { - if (auto pair = create_id(WRAP_EXPR(std::make_shared(std::forward(args)...)))) + if (auto pair = create_id(WRAP_EXPR(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()) }; + return{ pair->second, static_cast(pair->second.get()) }; } return nullptr; @@ -295,7 +295,7 @@ public: template static inline std::enable_if_t::value, u32> make(Args&&... args) { - if (auto pair = create_id(WRAP_EXPR(std::make_shared(std::forward(args)...)))) + if (auto pair = create_id(WRAP_EXPR(std::make_shared(std::forward(args)...)))) { id_manager::on_init::func(static_cast(pair->second.get()), pair->second); id_manager::on_stop::func(nullptr); @@ -306,10 +306,10 @@ public: } // 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(WRAP_EXPR(ptr))) + if (auto pair = create_id(WRAP_EXPR(ptr))) { id_manager::on_init::func(static_cast(pair->second.get()), pair->second); id_manager::on_stop::func(nullptr); @@ -320,53 +320,53 @@ public: } // Add a new ID for an object returned by provider() - template> - static inline std::shared_ptr import(F&& provider) + template> + static inline std::shared_ptr import(F&& provider) { - if (auto pair = create_id(std::forward(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()) }; + return { pair->second, static_cast(pair->second.get()) }; } return nullptr; } // Check whether the ID exists - template + template static inline bool check(u32 id) { reader_lock lock(g_mutex); - return find_id(get_type(), id) != nullptr; + return find_id(get_type(), get_type(), id) != nullptr; } // Get the ID - template - static inline std::shared_ptr get(u32 id) + template::value, T, Get>> + static inline std::shared_ptr get(u32 id) { reader_lock lock(g_mutex); - const auto found = find_id(get_type(), id); + const auto found = find_id(get_type(), get_type(), id); if (UNLIKELY(found == nullptr)) { return nullptr; } - return{ found->second, static_cast(found->second.get()) }; + return{ found->second, static_cast(found->second.get()) }; } // Conditionally get the ID, almost similar to select() but for the single object only. - template::second_type> + template::second_type> static inline auto get(u32 id, F&& pred) { using result_type = std::conditional_t::return_type>::value, void, std::shared_ptr>; reader_lock lock(g_mutex); - const auto found = find_id(get_type(), id); + const auto found = find_id(get_type(), get_type(), id); if (UNLIKELY(found == nullptr)) { @@ -404,19 +404,34 @@ public: } // Get count of objects - template + template static inline u32 get_count() { reader_lock lock(g_mutex); - return ::size32(g_map[get_type()]); + if (std::is_void::value) + { + return ::size32(g_map[get_type()]); + } + + u32 result = 0; + + for (auto& id : g_map[get_type()]) + { + if (id.first.type() == get_type()) + { + result++; + } + } + + return result; } // Remove the ID - template + template static inline bool remove(u32 id) { - auto&& ptr = delete_id(get_type(), get_tag(), id); + auto&& ptr = delete_id(get_type(), get_type(), get_tag(), id); if (LIKELY(ptr)) { @@ -427,28 +442,28 @@ public: } // Remove the ID and return it - template - static inline std::shared_ptr withdraw(u32 id) + template::value, T, Get>> + static inline std::shared_ptr withdraw(u32 id) { - auto&& ptr = delete_id(get_type(), get_tag(), id); + auto&& ptr = delete_id(get_type(), get_type(), get_tag(), id); if (LIKELY(ptr)) { id_manager::on_stop::func(static_cast(ptr.get())); } - return{ ptr, static_cast(ptr.get()) }; + return{ ptr, static_cast(ptr.get()) }; } // Conditionally remove the ID and return it. - template - static inline std::shared_ptr withdraw(u32 id, F&& pred) + template::value, T, Get>, typename F> + static inline std::shared_ptr withdraw(u32 id, F&& pred) { std::shared_ptr ptr; { writer_lock lock(g_mutex); - const auto found = find_id(get_type(), id); + const auto found = find_id(get_type(), get_type(), id); if (UNLIKELY(found == nullptr || !pred(id, *static_cast(found->second.get())))) { @@ -462,7 +477,7 @@ public: id_manager::on_stop::func(static_cast(ptr.get())); - return{ ptr, static_cast(ptr.get()) }; + return{ ptr, static_cast(ptr.get()) }; } };