diff --git a/rpcs3/Emu/IdManager.cpp b/rpcs3/Emu/IdManager.cpp index 10929fca16..051e1ca979 100644 --- a/rpcs3/Emu/IdManager.cpp +++ b/rpcs3/Emu/IdManager.cpp @@ -17,3 +17,17 @@ namespace idm g_cur_id = 1; // first ID } } + +namespace fxm +{ + std::mutex g_fx_mutex; + + std::unordered_map> g_fx_map; + + void clear() + { + std::lock_guard lock(g_fx_mutex); + + g_fx_map.clear(); + } +} diff --git a/rpcs3/Emu/IdManager.h b/rpcs3/Emu/IdManager.h index ed9c4154f9..0d614cba77 100644 --- a/rpcs3/Emu/IdManager.h +++ b/rpcs3/Emu/IdManager.h @@ -27,16 +27,9 @@ public: // ID Manager // 0 is invalid ID // 1..0x7fffffff : general purpose IDs -// 0x80000000+ : occupied by fixed IDs +// 0x80000000+ : reserved namespace idm { - // for internal use - inline u32 get_type_fixed_id(const std::type_info& type) - { - // TODO: better way of fixed ID generation - return 0x80000000 | static_cast(type.hash_code()); - } - // reinitialize ID manager void clear(); @@ -53,14 +46,6 @@ namespace idm return f != g_id_map.end() && f->second.info == typeid(T); } - // check if fixed ID exists - template bool check_fixed() - { - static const u32 id = get_type_fixed_id(typeid(T)); - - return check(id); - } - // must be called from the constructor called through make() or make_ptr() to get further ID of current object inline u32 get_current_id() { @@ -75,37 +60,6 @@ namespace idm return g_cur_id & 0x7fffffff; } - // add fixed ID of specified type only if it doesn't exist (each type has unique id) - template std::enable_if_t::value, std::shared_ptr> make_fixed(Args&&... args) - { - extern std::mutex g_id_mutex; - extern std::unordered_map g_id_map; - - static const u32 id = get_type_fixed_id(typeid(T)); - - std::lock_guard lock(g_id_mutex); - - const auto found = g_id_map.find(id); - - // ensure that this ID doesn't exist - if (found == g_id_map.end()) - { - auto ptr = std::make_shared(std::forward(args)...); - - g_id_map.emplace(id, ID_data_t(ptr)); - - return std::move(ptr); - } - - // ensure that this ID is not occupied by the object of another type - if (found->second.info == typeid(T)) - { - return nullptr; - } - - throw EXCEPTION("Collision occured ('%s' and '%s', id=0x%x)", found->second.info.name(), typeid(T).name(), id); - } - // add new ID of specified type with specified constructor arguments (returns object) template std::enable_if_t::value, std::shared_ptr> make_ptr(Args&&... args) { @@ -154,26 +108,6 @@ namespace idm throw EXCEPTION("Out of IDs"); } - // get fixed ID of specified type - template std::shared_ptr get_fixed() - { - extern std::mutex g_id_mutex; - extern std::unordered_map g_id_map; - - std::lock_guard lock(g_id_mutex); - - static const u32 id = get_type_fixed_id(typeid(T)); - - const auto found = g_id_map.find(id); - - if (found == g_id_map.end() || found->second.info != typeid(T)) - { - return nullptr; - } - - return std::static_pointer_cast(found->second.data); - } - // get ID of specified type template std::shared_ptr get(u32 id) { @@ -192,7 +126,7 @@ namespace idm return std::static_pointer_cast(found->second.data); } - // load all IDs of specified type T + // get all IDs of specified type T (unsorted) template std::vector> get_all() { extern std::mutex g_id_mutex; @@ -235,14 +169,6 @@ namespace idm return true; } - // remove fixed ID created with type T - template bool remove_fixed() - { - static const u32 id = get_type_fixed_id(typeid(T)); - - return remove(id); - } - template u32 get_count() { extern std::mutex g_id_mutex; @@ -310,4 +236,83 @@ namespace idm return result; } -}; +} + +// Fixed Object Manager +// allows to manage shared objects of any specified type, but only one object per type; +// object are deleted when the emulation is stopped +namespace fxm +{ + // reinitialize + void clear(); + + // add fixed object of specified type only if it doesn't exist (one unique object per type may exist) + template std::enable_if_t::value, std::shared_ptr> make(Args&&... args) + { + extern std::mutex g_fx_mutex; + extern std::unordered_map> g_fx_map; + + std::lock_guard lock(g_fx_mutex); + + const auto found = g_fx_map.find(typeid(T)); + + // only if object of this type doesn't exist + if (found == g_fx_map.end()) + { + auto ptr = std::make_shared(std::forward(args)...); + + g_fx_map.emplace(typeid(T), ptr); + + return std::move(ptr); + } + + return nullptr; + } + + // check whether the object exists + template bool check() + { + extern std::mutex g_fx_mutex; + extern std::unordered_map> g_fx_map; + + std::lock_guard lock(g_fx_mutex); + + return g_fx_map.find(typeid(T)) != g_fx_map.end(); + } + + // get fixed object of specified type + template std::shared_ptr get() + { + extern std::mutex g_fx_mutex; + extern std::unordered_map> g_fx_map; + + std::lock_guard lock(g_fx_mutex); + + const auto found = g_fx_map.find(typeid(T)); + + if (found == g_fx_map.end()) + { + return nullptr; + } + + return std::static_pointer_cast(found->second); + } + + // remove fixed object created with type T + template bool remove() + { + extern std::mutex g_fx_mutex; + extern std::unordered_map> g_fx_map; + + std::lock_guard lock(g_fx_mutex); + + const auto found = g_fx_map.find(typeid(T)); + + if (found == g_fx_map.end()) + { + return false; + } + + return g_fx_map.erase(found), true; + } +} diff --git a/rpcs3/Emu/SysCalls/Modules/cellCamera.cpp b/rpcs3/Emu/SysCalls/Modules/cellCamera.cpp index 82a8079241..b7b3dd4cad 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellCamera.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellCamera.cpp @@ -87,7 +87,7 @@ s32 cellCameraInit() return CELL_CAMERA_ERROR_DEVICE_NOT_FOUND; } - const auto camera = idm::make_fixed(); + const auto camera = fxm::make(); if (!camera) { @@ -138,7 +138,7 @@ s32 cellCameraEnd() { cellCamera.Warning("cellCameraEnd()"); - if (!idm::remove_fixed()) + if (!fxm::remove()) { return CELL_CAMERA_ERROR_NOT_INIT; } @@ -174,7 +174,7 @@ s32 cellCameraGetType(s32 dev_num, vm::ptr type) { cellCamera.Warning("cellCameraGetType(dev_num=%d, type=*0x%x)", dev_num, type); - const auto camera = idm::get_fixed(); + const auto camera = fxm::get(); if (!camera) { @@ -228,7 +228,7 @@ s32 cellCameraGetAttribute(s32 dev_num, s32 attrib, vm::ptr arg1, vm::ptr(); + const auto camera = fxm::get(); if (!camera) { @@ -252,7 +252,7 @@ s32 cellCameraSetAttribute(s32 dev_num, s32 attrib, u32 arg1, u32 arg2) const auto attr_name = get_camera_attr_name(attrib); - const auto camera = idm::get_fixed(); + const auto camera = fxm::get(); if (!camera) { diff --git a/rpcs3/Emu/SysCalls/Modules/cellRudp.cpp b/rpcs3/Emu/SysCalls/Modules/cellRudp.cpp index 729136fef8..affb101541 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellRudp.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellRudp.cpp @@ -24,7 +24,7 @@ s32 cellRudpInit(vm::ptr allocator) { cellRudp.Warning("cellRudpInit(allocator=*0x%x)", allocator); - const auto rudp = idm::make_fixed(); + const auto rudp = fxm::make(); if (!rudp) { @@ -59,7 +59,7 @@ s32 cellRudpEnd() { cellRudp.Warning("cellRudpEnd()"); - if (!idm::remove_fixed()) + if (!fxm::remove()) { return CELL_RUDP_ERROR_NOT_INITIALIZED; } @@ -77,7 +77,7 @@ s32 cellRudpSetEventHandler(vm::ptr handler, vm::ptr { cellRudp.Todo("cellRudpSetEventHandler(handler=*0x%x, arg=*0x%x)", handler, arg); - const auto rudp = idm::get_fixed(); + const auto rudp = fxm::get(); if (!rudp) { diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 8c975105a6..2e53fe28b8 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -374,8 +374,9 @@ void Emulator::Stop() LOG_NOTICE(GENERAL, "All threads stopped..."); idm::clear(); + fxm::clear(); - LOG_NOTICE(GENERAL, "ID manager cleared..."); + LOG_NOTICE(GENERAL, "Objects cleared..."); finalize_psv_modules(); clear_all_psv_objects(); diff --git a/rpcs3/stdafx.h b/rpcs3/stdafx.h index ffe5e3d525..cd97eb20ee 100644 --- a/rpcs3/stdafx.h +++ b/rpcs3/stdafx.h @@ -39,6 +39,7 @@ #include #include #include +#include #include "Utilities/GNU.h"