mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 03:25:16 +00:00
core: Move IDM to FXO
This commit is contained in:
parent
bf1756448e
commit
4a9be0a8d2
3 changed files with 43 additions and 68 deletions
|
@ -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<u32, u32> invl_range)
|
||||
idm::map_data* idm::allocate_id(std::vector<map_data>& vec, u32 type_id, u32 base, u32 step, u32 count, std::pair<u32, u32> 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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,12 @@
|
|||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "util/fixed_typemap.hpp"
|
||||
|
||||
extern stx::manual_typemap<void, 0x20'00000, 128> 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<std::pair<id_key, std::shared_ptr<void>>>;
|
||||
template <typename T>
|
||||
struct id_map
|
||||
{
|
||||
std::vector<std::pair<id_key, std::shared_ptr<void>>> 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<id_manager::id_map> g_map;
|
||||
|
||||
template <typename T>
|
||||
static inline u32 get_type()
|
||||
{
|
||||
|
@ -248,12 +262,14 @@ class idm
|
|||
}
|
||||
};
|
||||
|
||||
using map_data = std::pair<id_manager::id_key, std::shared_ptr<void>>;
|
||||
|
||||
// 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<u32, u32> invl_range);
|
||||
static map_data* allocate_id(std::vector<map_data>& vec, u32 type_id, u32 base, u32 step, u32 count, std::pair<u32, u32> invl_range);
|
||||
|
||||
// Find ID (additionally check type if types are not equal)
|
||||
template <typename T, typename Type>
|
||||
static id_manager::id_map::pointer find_id(u32 id)
|
||||
static map_data* find_id(u32 id)
|
||||
{
|
||||
static_assert(id_manager::id_verify<T, Type>::value, "Invalid ID type combination");
|
||||
|
||||
|
@ -264,7 +280,7 @@ class idm
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
auto& vec = g_map[get_type<T>()];
|
||||
auto& vec = g_fxo->get<id_manager::id_map<T>>().vec;
|
||||
|
||||
if (index >= vec.size())
|
||||
{
|
||||
|
@ -289,20 +305,19 @@ class idm
|
|||
|
||||
// Allocate new ID and assign the object from the provider()
|
||||
template <typename T, typename Type, typename F>
|
||||
static id_manager::id_map::pointer create_id(F&& provider)
|
||||
static map_data* create_id(F&& provider)
|
||||
{
|
||||
static_assert(id_manager::id_verify<T, Type>::value, "Invalid ID type combination");
|
||||
|
||||
// ID info
|
||||
const id_manager::id_key info{get_type<T>(), get_type<Type>()};
|
||||
|
||||
// ID traits
|
||||
using traits = id_manager::id_traits<Type>;
|
||||
|
||||
// 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<id_manager::id_map<T>>();
|
||||
|
||||
if (auto* place = allocate_id(map.vec, get_type<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 <typename T>
|
||||
static inline void clear()
|
||||
{
|
||||
std::lock_guard lock(id_manager::g_mutex);
|
||||
g_map[id_manager::typeinfo::get_index<T>()].clear();
|
||||
g_fxo->get<id_manager::id_map<T>>().vec.clear();
|
||||
}
|
||||
|
||||
// Get last ID (updated in create_id/allocate_id)
|
||||
|
@ -387,7 +397,7 @@ public:
|
|||
|
||||
// Access the ID record without locking (unsafe)
|
||||
template <typename T, typename Get = T>
|
||||
static inline id_manager::id_map::pointer find_unlocked(u32 id)
|
||||
static inline map_data* find_unlocked(u32 id)
|
||||
{
|
||||
return find_id<T, Get>(id);
|
||||
}
|
||||
|
@ -508,7 +518,7 @@ public:
|
|||
|
||||
u32 result = 0;
|
||||
|
||||
for (auto& id : g_map[get_type<T>()])
|
||||
for (auto& id : g_fxo->get<id_manager::id_map<T>>().vec)
|
||||
{
|
||||
if (id.second)
|
||||
{
|
||||
|
@ -534,7 +544,7 @@ public:
|
|||
|
||||
reader_lock lock(id_manager::g_mutex);
|
||||
|
||||
for (auto& id : g_map[get_type<T>()])
|
||||
for (auto& id : g_fxo->get<id_manager::id_map<T>>().vec)
|
||||
{
|
||||
if (auto ptr = static_cast<object_type*>(id.second.get()))
|
||||
{
|
||||
|
@ -643,9 +653,3 @@ public:
|
|||
return {nullptr};
|
||||
}
|
||||
};
|
||||
|
||||
#include "util/fixed_typemap.hpp"
|
||||
|
||||
extern stx::manual_typemap<void, 0x20'00000, 128> g_fixed_typemap;
|
||||
|
||||
constexpr auto* g_fxo = &g_fixed_typemap;
|
||||
|
|
|
@ -138,7 +138,6 @@ void Emulator::Init(bool add_only)
|
|||
}
|
||||
}
|
||||
|
||||
idm::init();
|
||||
g_fxo->reset();
|
||||
g_fxo->need<named_thread<progress_dialog_server>>();
|
||||
|
||||
|
@ -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<ppu_module>();
|
||||
g_fxo->init<id_manager::id_map<lv2_obj>>();
|
||||
g_fxo->init<id_manager::id_map<named_thread<ppu_thread>>>();
|
||||
|
||||
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...");
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue