sys_prx: Make PPU imports/exports thread-safe

This commit is contained in:
Eladash 2022-11-05 15:29:44 +02:00 committed by Ivan
parent e98b07de03
commit 0a35a62235

View file

@ -24,6 +24,7 @@
#include <map> #include <map>
#include <set> #include <set>
#include <algorithm> #include <algorithm>
#include <shared_mutex>
#include "util/asm.hpp" #include "util/asm.hpp"
LOG_CHANNEL(ppu_loader); LOG_CHANNEL(ppu_loader);
@ -143,15 +144,16 @@ struct ppu_linkage_info
}; };
// FNID -> (export; [imports...]) // FNID -> (export; [imports...])
std::unordered_map<u32, info, value_hash<u32>> functions{}; std::map<u32, info> functions{};
std::unordered_map<u32, info, value_hash<u32>> variables{}; std::map<u32, info> variables{};
// Obsolete // Obsolete
bool imported = false; bool imported = false;
}; };
// Module map // Module map
std::unordered_map<std::string, module_data> modules{}; std::map<std::string, module_data> modules{};
shared_mutex mutex;
}; };
// Initialize static modules. // Initialize static modules.
@ -631,6 +633,8 @@ static auto ppu_load_exports(ppu_linkage_info* link, u32 exports_start, u32 expo
{ {
std::unordered_map<u32, u32> result; std::unordered_map<u32, u32> result;
std::lock_guard lock(link->mutex);
for (u32 addr = exports_start; addr < exports_end;) for (u32 addr = exports_start; addr < exports_end;)
{ {
const auto& lib = vm::_ref<const ppu_prx_module_info>(addr); const auto& lib = vm::_ref<const ppu_prx_module_info>(addr);
@ -777,6 +781,8 @@ static auto ppu_load_imports(std::vector<ppu_reloc>& relocs, ppu_linkage_info* l
{ {
std::unordered_map<u32, void*> result; std::unordered_map<u32, void*> result;
reader_lock lock(link->mutex);
for (u32 addr = imports_start; addr < imports_end;) for (u32 addr = imports_start; addr < imports_end;)
{ {
const auto& lib = vm::_ref<const ppu_prx_module_info>(addr); const auto& lib = vm::_ref<const ppu_prx_module_info>(addr);
@ -1498,9 +1504,16 @@ std::shared_ptr<lv2_prx> ppu_load_prx(const ppu_prx_object& elf, const std::stri
void ppu_unload_prx(const lv2_prx& prx) void ppu_unload_prx(const lv2_prx& prx)
{ {
std::unique_lock lock(g_fxo->get<ppu_linkage_info>().mutex, std::defer_lock);
// Clean linkage info // Clean linkage info
for (auto& imp : prx.imports) for (auto& imp : prx.imports)
{ {
if (!lock)
{
lock.lock();
}
auto pinfo = static_cast<ppu_linkage_info::module_data::info*>(imp.second); auto pinfo = static_cast<ppu_linkage_info::module_data::info*>(imp.second);
pinfo->frefss.erase(imp.first); pinfo->frefss.erase(imp.first);
pinfo->imports.erase(imp.first); pinfo->imports.erase(imp.first);
@ -1523,6 +1536,11 @@ void ppu_unload_prx(const lv2_prx& prx)
// } // }
//} //}
if (lock)
{
lock.unlock();
}
if (prx.path.ends_with("sys/external/liblv2.sprx"sv)) if (prx.path.ends_with("sys/external/liblv2.sprx"sv))
{ {
liblv2_begin = 0; liblv2_begin = 0;