From 803e6b017bf8bb82ee65b48fa244eb1e4c89034d Mon Sep 17 00:00:00 2001 From: JosJuice Date: Mon, 30 Jun 2025 19:12:00 +0200 Subject: PPCSymbolDB: Reduce lock contention in LoadMap/LoadMapOnBoot By building the map in a local variable and then swapping it with the member variable, we avoid the need to hold a lock while building the map. --- Source/Core/Common/SymbolDB.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'Source/Core/Common/SymbolDB.cpp') diff --git a/Source/Core/Common/SymbolDB.cpp b/Source/Core/Common/SymbolDB.cpp index 88f281e497..ad438b8277 100644 --- a/Source/Core/Common/SymbolDB.cpp +++ b/Source/Core/Common/SymbolDB.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -49,6 +50,8 @@ bool SymbolDB::IsEmpty() const bool SymbolDB::Clear(const char* prefix) { + std::lock_guard lock(m_mutex); + // TODO: honor prefix m_map_name.clear(); if (IsEmpty()) @@ -61,9 +64,14 @@ bool SymbolDB::Clear(const char* prefix) } void SymbolDB::Index() +{ + Index(&m_functions); +} + +void SymbolDB::Index(XFuncMap* functions) { int i = 0; - for (auto& func : m_functions) + for (auto& func : *functions) { func.second.index = i++; } -- cgit v1.2.3 From fef77a5f20d03f22315b2d77f7970c3fed895b13 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Mon, 30 Jun 2025 19:26:24 +0200 Subject: PPCSymbolDB: Add missing locking 9395238 added locking in some PPCSymbolDB functions that access member variables, but far from all. To ensure thread safety, this commit adds the missing locking. --- Source/Core/Common/SymbolDB.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'Source/Core/Common/SymbolDB.cpp') diff --git a/Source/Core/Common/SymbolDB.cpp b/Source/Core/Common/SymbolDB.cpp index ad438b8277..0784256f0b 100644 --- a/Source/Core/Common/SymbolDB.cpp +++ b/Source/Core/Common/SymbolDB.cpp @@ -35,6 +35,7 @@ void Symbol::Rename(const std::string& symbol_name) void SymbolDB::List() { + std::lock_guard lock(m_mutex); for (const auto& func : m_functions) { DEBUG_LOG_FMT(OSHLE, "{} @ {:08x}: {} bytes (hash {:08x}) : {} calls", func.second.name, @@ -45,6 +46,7 @@ void SymbolDB::List() bool SymbolDB::IsEmpty() const { + std::lock_guard lock(m_mutex); return m_functions.empty() && m_notes.empty(); } @@ -65,6 +67,7 @@ bool SymbolDB::Clear(const char* prefix) void SymbolDB::Index() { + std::lock_guard lock(m_mutex); Index(&m_functions); } @@ -79,6 +82,8 @@ void SymbolDB::Index(XFuncMap* functions) Symbol* SymbolDB::GetSymbolFromName(std::string_view name) { + std::lock_guard lock(m_mutex); + for (auto& func : m_functions) { if (func.second.function_name == name) @@ -90,6 +95,7 @@ Symbol* SymbolDB::GetSymbolFromName(std::string_view name) std::vector SymbolDB::GetSymbolsFromName(std::string_view name) { + std::lock_guard lock(m_mutex); std::vector symbols; for (auto& func : m_functions) @@ -103,6 +109,8 @@ std::vector SymbolDB::GetSymbolsFromName(std::string_view name) Symbol* SymbolDB::GetSymbolFromHash(u32 hash) { + std::lock_guard lock(m_mutex); + auto iter = m_checksum_to_function.find(hash); if (iter == m_checksum_to_function.end()) return nullptr; @@ -112,6 +120,8 @@ Symbol* SymbolDB::GetSymbolFromHash(u32 hash) std::vector SymbolDB::GetSymbolsFromHash(u32 hash) { + std::lock_guard lock(m_mutex); + const auto iter = m_checksum_to_function.find(hash); if (iter == m_checksum_to_function.cend()) @@ -122,6 +132,7 @@ std::vector SymbolDB::GetSymbolsFromHash(u32 hash) void SymbolDB::AddCompleteSymbol(const Symbol& symbol) { + std::lock_guard lock(m_mutex); m_functions.emplace(symbol.address, symbol); } } // namespace Common -- cgit v1.2.3 From 9f32562e3633b62526918cbf0cfb920b96a263da Mon Sep 17 00:00:00 2001 From: JosJuice Date: Mon, 30 Jun 2025 21:31:06 +0200 Subject: PPCSymbolDB: Don't return non-const pointers For thread safety, we shouldn't return any pointers or references that can be used to mutate the state of the PPCSymbolDB. This should be the final part of making PPCSymbolDB thread safe unless I've missed something. --- Source/Core/Common/SymbolDB.cpp | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) (limited to 'Source/Core/Common/SymbolDB.cpp') diff --git a/Source/Core/Common/SymbolDB.cpp b/Source/Core/Common/SymbolDB.cpp index 0784256f0b..2fa514ba86 100644 --- a/Source/Core/Common/SymbolDB.cpp +++ b/Source/Core/Common/SymbolDB.cpp @@ -80,7 +80,7 @@ void SymbolDB::Index(XFuncMap* functions) } } -Symbol* SymbolDB::GetSymbolFromName(std::string_view name) +const Symbol* SymbolDB::GetSymbolFromName(std::string_view name) const { std::lock_guard lock(m_mutex); @@ -93,10 +93,10 @@ Symbol* SymbolDB::GetSymbolFromName(std::string_view name) return nullptr; } -std::vector SymbolDB::GetSymbolsFromName(std::string_view name) +std::vector SymbolDB::GetSymbolsFromName(std::string_view name) const { std::lock_guard lock(m_mutex); - std::vector symbols; + std::vector symbols; for (auto& func : m_functions) { @@ -107,7 +107,7 @@ std::vector SymbolDB::GetSymbolsFromName(std::string_view name) return symbols; } -Symbol* SymbolDB::GetSymbolFromHash(u32 hash) +const Symbol* SymbolDB::GetSymbolFromHash(u32 hash) const { std::lock_guard lock(m_mutex); @@ -118,7 +118,7 @@ Symbol* SymbolDB::GetSymbolFromHash(u32 hash) return *iter->second.begin(); } -std::vector SymbolDB::GetSymbolsFromHash(u32 hash) +std::vector SymbolDB::GetSymbolsFromHash(u32 hash) const { std::lock_guard lock(m_mutex); @@ -133,6 +133,33 @@ std::vector SymbolDB::GetSymbolsFromHash(u32 hash) void SymbolDB::AddCompleteSymbol(const Symbol& symbol) { std::lock_guard lock(m_mutex); - m_functions.emplace(symbol.address, symbol); + m_functions[symbol.address] = symbol; } + +bool SymbolDB::RenameSymbol(const Symbol& symbol, const std::string& symbol_name) +{ + std::lock_guard lock(m_mutex); + + auto it = m_functions.find(symbol.address); + if (it == m_functions.end()) + return false; + + it->second.Rename(symbol_name); + return true; +} + +bool SymbolDB::RenameSymbol(const Symbol& symbol, const std::string& symbol_name, + const std::string& object_name) +{ + std::lock_guard lock(m_mutex); + + auto it = m_functions.find(symbol.address); + if (it == m_functions.end()) + return false; + + it->second.Rename(symbol_name); + it->second.object_name = object_name; + return true; +} + } // namespace Common -- cgit v1.2.3