From 4a9be0a8d2757d351b32b8f6d82ff6450236518d Mon Sep 17 00:00:00 2001 From: Eladash Date: Tue, 30 Mar 2021 19:37:51 +0300 Subject: [PATCH] core: Move IDM to FXO --- rpcs3/Emu/IdManager.cpp | 35 +++---------------------- rpcs3/Emu/IdManager.h | 58 ++++++++++++++++++++++------------------- rpcs3/Emu/System.cpp | 18 ++++++------- 3 files changed, 43 insertions(+), 68 deletions(-) diff --git a/rpcs3/Emu/IdManager.cpp b/rpcs3/Emu/IdManager.cpp index 9f001ac9b2..54862d7716 100644 --- a/rpcs3/Emu/IdManager.cpp +++ b/rpcs3/Emu/IdManager.cpp @@ -5,22 +5,15 @@ shared_mutex id_manager::g_mutex; thread_local DECLARE(idm::g_id); -DECLARE(idm::g_map); -id_manager::id_map::pointer idm::allocate_id(const id_manager::id_key& info, u32 base, u32 step, u32 count, std::pair invl_range) +idm::map_data* idm::allocate_id(std::vector& vec, u32 type_id, u32 base, u32 step, u32 count, std::pair invl_range) { - // Base type id is stored in value - auto& vec = g_map[info.value()]; - - // Preallocate memory - vec.reserve(count); - if (vec.size() < count) { // Try to emplace back const u32 _next = base + step * ::size32(vec); g_id = _next; - vec.emplace_back(id_manager::id_key(_next, info.type()), nullptr); + vec.emplace_back(id_manager::id_key(_next, type_id), nullptr); return &vec.back(); } @@ -35,7 +28,7 @@ id_manager::id_map::pointer idm::allocate_id(const id_manager::id_key& info, u32 // Incremenet ID invalidation counter const u32 id = next | ((ptr->first + (1u << invl_range.first)) & (invl_range.second ? (((1u << invl_range.second) - 1) << invl_range.first) : 0)); g_id = id; - ptr->first = id_manager::id_key(id, info.type()); + ptr->first = id_manager::id_key(id, type_id); return ptr; } } @@ -43,25 +36,3 @@ id_manager::id_map::pointer idm::allocate_id(const id_manager::id_key& info, u32 // Out of IDs return nullptr; } - -void idm::init() -{ - // Allocate - g_map.resize(id_manager::typeinfo::get_count()); - idm::clear(); -} - -void idm::clear() -{ - // Call recorded finalization functions for all IDs - for (auto& map : g_map) - { - for (auto& pair : map) - { - pair.second.reset(); - pair.first = {}; - } - - map.clear(); - } -} diff --git a/rpcs3/Emu/IdManager.h b/rpcs3/Emu/IdManager.h index 53d8a2b087..61434f5a81 100644 --- a/rpcs3/Emu/IdManager.h +++ b/rpcs3/Emu/IdManager.h @@ -6,6 +6,12 @@ #include #include +#include "util/fixed_typemap.hpp" + +extern stx::manual_typemap g_fixed_typemap; + +constexpr auto* g_fxo = &g_fixed_typemap; + // Helper namespace namespace id_manager { @@ -132,7 +138,18 @@ namespace id_manager } }; - using id_map = std::vector>>; + template + struct id_map + { + std::vector>> vec; + shared_mutex mutex; // TODO: Use this instead of global mutex + + id_map() + { + // Preallocate memory + vec.reserve(T::id_count); + } + }; } // Object manager for emulated process. Multiple objects of specified arbitrary type are given unique IDs. @@ -141,9 +158,6 @@ class idm // Last allocated ID for constructors static thread_local u32 g_id; - // Type Index -> ID -> Object. Use global since only one process is supported atm. - static std::vector g_map; - template static inline u32 get_type() { @@ -248,12 +262,14 @@ class idm } }; + using map_data = std::pair>; + // Prepare new ID (returns nullptr if out of resources) - static id_manager::id_map::pointer allocate_id(const id_manager::id_key& info, u32 base, u32 step, u32 count, std::pair invl_range); + static map_data* allocate_id(std::vector& vec, u32 type_id, u32 base, u32 step, u32 count, std::pair invl_range); // Find ID (additionally check type if types are not equal) template - static id_manager::id_map::pointer find_id(u32 id) + static map_data* find_id(u32 id) { static_assert(id_manager::id_verify::value, "Invalid ID type combination"); @@ -264,7 +280,7 @@ class idm return nullptr; } - auto& vec = g_map[get_type()]; + auto& vec = g_fxo->get>().vec; if (index >= vec.size()) { @@ -289,20 +305,19 @@ class idm // Allocate new ID and assign the object from the provider() template - static id_manager::id_map::pointer create_id(F&& provider) + static map_data* create_id(F&& provider) { static_assert(id_manager::id_verify::value, "Invalid ID type combination"); - // ID info - const id_manager::id_key info{get_type(), get_type()}; - // ID traits using traits = id_manager::id_traits; // Allocate new id std::lock_guard lock(id_manager::g_mutex); - if (auto* place = allocate_id(info, traits::base, traits::step, traits::count, traits::invl_range)) + auto& map = g_fxo->get>(); + + if (auto* place = allocate_id(map.vec, get_type(), traits::base, traits::step, traits::count, traits::invl_range)) { // Get object, store it place->second = provider(); @@ -317,18 +332,13 @@ class idm } public: - // Initialize object manager - static void init(); - - // Remove all objects - static void clear(); // Remove all objects of a type template static inline void clear() { std::lock_guard lock(id_manager::g_mutex); - g_map[id_manager::typeinfo::get_index()].clear(); + g_fxo->get>().vec.clear(); } // Get last ID (updated in create_id/allocate_id) @@ -387,7 +397,7 @@ public: // Access the ID record without locking (unsafe) template - static inline id_manager::id_map::pointer find_unlocked(u32 id) + static inline map_data* find_unlocked(u32 id) { return find_id(id); } @@ -508,7 +518,7 @@ public: u32 result = 0; - for (auto& id : g_map[get_type()]) + for (auto& id : g_fxo->get>().vec) { if (id.second) { @@ -534,7 +544,7 @@ public: reader_lock lock(id_manager::g_mutex); - for (auto& id : g_map[get_type()]) + for (auto& id : g_fxo->get>().vec) { if (auto ptr = static_cast(id.second.get())) { @@ -643,9 +653,3 @@ public: return {nullptr}; } }; - -#include "util/fixed_typemap.hpp" - -extern stx::manual_typemap g_fixed_typemap; - -constexpr auto* g_fxo = &g_fixed_typemap; diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 9b4f67aa5b..7f4a6762af 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -138,7 +138,6 @@ void Emulator::Init(bool add_only) } } - idm::init(); g_fxo->reset(); g_fxo->need>(); @@ -1620,6 +1619,9 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool return game_boot_result::decryption_error; } + m_state = system_state::ready; + vm::init(); + ppu_exec_object ppu_exec; ppu_prx_object ppu_prx; spu_exec_object spu_exec; @@ -1627,11 +1629,8 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool if (ppu_exec.open(elf_file) == elf_error::ok) { // PS3 executable - m_state = system_state::ready; GetCallbacks().on_ready(); - vm::init(); - if (argv.empty()) { argv.resize(1); @@ -1669,6 +1668,8 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool } g_fxo->init(); + g_fxo->init>(); + g_fxo->init>>(); if (ppu_load_exec(ppu_exec)) { @@ -1688,6 +1689,7 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool if (ppu_exec != elf_error::ok) { + SetForceBoot(true); Stop(); sys_log.error("Invalid or unsupported PPU executable format: %s", elf_path); @@ -1698,18 +1700,14 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool else if (ppu_prx.open(elf_file) == elf_error::ok) { // PPU PRX (experimental) - m_state = system_state::ready; GetCallbacks().on_ready(); - vm::init(); g_fxo->init(false); ppu_load_prx(ppu_prx, m_path); } else if (spu_exec.open(elf_file) == elf_error::ok) { // SPU executable (experimental) - m_state = system_state::ready; GetCallbacks().on_ready(); - vm::init(); g_fxo->init(false); spu_load_exec(spu_exec); } @@ -1720,6 +1718,9 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool sys_log.warning("** ppu_exec -> %s", ppu_exec.get_error()); sys_log.warning("** ppu_prx -> %s", ppu_prx.get_error()); sys_log.warning("** spu_exec -> %s", spu_exec.get_error()); + + SetForceBoot(true); + Stop(); return game_boot_result::invalid_file_or_folder; } @@ -1973,7 +1974,6 @@ void Emulator::Stop(bool restart) sys_log.notice("All threads have been stopped."); lv2_obj::cleanup(); - idm::clear(); sys_log.notice("Objects cleared...");