Added a mutex to the debug symbol table access functions to ensure that access to symbol maps is thread safe. Since a map change will invalidate any iterators operating on the map, it is important to ensure that access to the map is locked when a thread is iterating or operating on the map.

This commit is contained in:
harry 2023-01-31 22:14:49 -05:00
parent 5cec622e58
commit d32ab0ad51
6 changed files with 139 additions and 2 deletions

View File

@ -502,6 +502,7 @@ set(SRC_CORE
${CMAKE_CURRENT_SOURCE_DIR}/utils/guid.cpp
${CMAKE_CURRENT_SOURCE_DIR}/utils/md5.cpp
${CMAKE_CURRENT_SOURCE_DIR}/utils/memory.cpp
${CMAKE_CURRENT_SOURCE_DIR}/utils/mutex.cpp
)

View File

@ -215,16 +215,23 @@ void debugSymbolPage_t::print(void)
//--------------------------------------------------------------
debugSymbolTable_t::debugSymbolTable_t(void)
{
cs = new FCEU::mutex();
}
//--------------------------------------------------------------
debugSymbolTable_t::~debugSymbolTable_t(void)
{
this->clear();
if (cs)
{
delete cs;
}
}
//--------------------------------------------------------------
void debugSymbolTable_t::clear(void)
{
FCEU::autoScopedLock alock(cs);
std::map <int, debugSymbolPage_t*>::iterator it;
for (it=pageMap.begin(); it!=pageMap.end(); it++)
@ -305,6 +312,7 @@ int debugSymbolTable_t::loadFileNL( int bank )
char stmp[512], line[512];
debugSymbolPage_t *page = NULL;
debugSymbol_t *sym = NULL;
FCEU::autoScopedLock alock(cs);
//printf("Looking to Load Debug Bank: $%X \n", bank );
@ -544,6 +552,7 @@ int debugSymbolTable_t::loadFileNL( int bank )
//--------------------------------------------------------------
int debugSymbolTable_t::loadRegisterMap(void)
{
FCEU::autoScopedLock alock(cs);
debugSymbolPage_t *page;
page = new debugSymbolPage_t();
@ -627,6 +636,7 @@ int debugSymbolTable_t::addSymbolAtBankOffset( int bank, int ofs, debugSymbol_t
{
debugSymbolPage_t *page;
std::map <int, debugSymbolPage_t*>::iterator it;
FCEU::autoScopedLock alock(cs);
it = pageMap.find( bank );
@ -649,6 +659,7 @@ int debugSymbolTable_t::deleteSymbolAtBankOffset( int bank, int ofs )
{
debugSymbolPage_t *page;
std::map <int, debugSymbolPage_t*>::iterator it;
FCEU::autoScopedLock alock(cs);
it = pageMap.find( bank );
@ -666,6 +677,8 @@ int debugSymbolTable_t::deleteSymbolAtBankOffset( int bank, int ofs )
//--------------------------------------------------------------
debugSymbol_t *debugSymbolTable_t::getSymbolAtBankOffset( int bank, int ofs )
{
FCEU::autoScopedLock alock(cs);
auto it = pageMap.find( bank );
return it != pageMap.end() ? it->second->getSymbolAtOffset( ofs ) : NULL;
@ -673,6 +686,8 @@ debugSymbol_t *debugSymbolTable_t::getSymbolAtBankOffset( int bank, int ofs )
//--------------------------------------------------------------
debugSymbol_t *debugSymbolTable_t::getSymbol( int bank, const std::string &name )
{
FCEU::autoScopedLock alock(cs);
auto it = pageMap.find( bank );
return it != pageMap.end() ? it->second->getSymbol( name ) : NULL;
@ -680,6 +695,8 @@ debugSymbol_t *debugSymbolTable_t::getSymbol( int bank, const std::string &name
//--------------------------------------------------------------
debugSymbol_t *debugSymbolTable_t::getSymbolAtAnyBank( const std::string &name )
{
FCEU::autoScopedLock alock(cs);
for (auto &page : pageMap)
{
auto sym = getSymbol( page.first, name );
@ -697,6 +714,7 @@ void debugSymbolTable_t::save(void)
{
debugSymbolPage_t *page;
std::map <int, debugSymbolPage_t*>::iterator it;
FCEU::autoScopedLock alock(cs);
for (it=pageMap.begin(); it!=pageMap.end(); it++)
{
@ -710,6 +728,7 @@ void debugSymbolTable_t::print(void)
{
debugSymbolPage_t *page;
std::map <int, debugSymbolPage_t*>::iterator it;
FCEU::autoScopedLock alock(cs);
for (it=pageMap.begin(); it!=pageMap.end(); it++)
{

View File

@ -4,6 +4,8 @@
#include <string>
#include <map>
#include "utils/mutex.h"
struct debugSymbol_t
{
int ofs;
@ -103,6 +105,7 @@ class debugSymbolTable_t
private:
std::map <int, debugSymbolPage_t*> pageMap;
FCEU::mutex *cs;
int loadRegisterMap(void);

71
src/utils/mutex.cpp Normal file
View File

@ -0,0 +1,71 @@
// mutex.cpp
#include <cstdio>
#include "mutex.h"
namespace FCEU
{
//-----------------------------------------------------
// Cross platform mutex
// __QT_DRIVER__ multi-threaded application that uses Qt mutex implementation for synchronization
// __WIN_DRIVER__ is single thread application so sync methods are unimplemented.
//-----------------------------------------------------
mutex::mutex(void)
{
#ifdef __QT_DRIVER__
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
mtx = new QRecursiveMutex();
#else
mtx = new QMutex( QMutex::Recursive );
#endif
#endif
}
mutex::~mutex(void)
{
#ifdef __QT_DRIVER__
if (mtx)
{
delete mtx;
mtx = nullptr;
}
#endif
}
void mutex::lock(void)
{
#ifdef __QT_DRIVER__
mtx->lock();
#endif
}
void mutex::unlock(void)
{
#ifdef __QT_DRIVER__
mtx->unlock();
#endif
}
//-----------------------------------------------------
// Scoped AutoLock
//-----------------------------------------------------
autoScopedLock::autoScopedLock( mutex *mtx )
{
m = mtx;
if (m)
{
m->lock();
}
}
autoScopedLock::~autoScopedLock(void)
{
if (m)
{
m->unlock();
}
}
};

41
src/utils/mutex.h Normal file
View File

@ -0,0 +1,41 @@
// mutex.h
#ifdef __QT_DRIVER__
#include <QMutex>
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
#include <QRecursiveMutex>
#endif
#endif
namespace FCEU
{
class mutex
{
public:
mutex(void);
~mutex(void);
void lock(void);
void unlock(void);
private:
#ifdef __QT_DRIVER__
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
QRecursiveMutex *mtx;
#else
QMutex *mtx;
#endif
#endif
};
class autoScopedLock
{
public:
autoScopedLock( mutex *mtx );
~autoScopedLock(void);
private:
mutex *m;
};
};

View File

@ -743,6 +743,7 @@ xcopy /y /d "$(ProjectDir)\..\src\drivers\win\7z_64.dll" "$(OutDir)"</Command>
<ClCompile Include="..\src\utils\ioapi.cpp" />
<ClCompile Include="..\src\utils\md5.cpp" />
<ClCompile Include="..\src\utils\memory.cpp" />
<ClCompile Include="..\src\utils\mutex.cpp" />
<ClCompile Include="..\src\utils\unzip.cpp" />
<ClCompile Include="..\src\utils\xstring.cpp" />
<ClCompile Include="..\src\lua\src\lapi.c">
@ -1145,6 +1146,7 @@ xcopy /y /d "$(ProjectDir)\..\src\drivers\win\7z_64.dll" "$(OutDir)"</Command>
<ClInclude Include="..\src\utils\ioapi.h" />
<ClInclude Include="..\src\utils\md5.h" />
<ClInclude Include="..\src\utils\memory.h" />
<ClInclude Include="..\src\utils\mutex.h" />
<ClInclude Include="..\src\utils\unzip.h" />
<ClInclude Include="..\src\utils\valuearray.h" />
<ClInclude Include="..\src\utils\xstring.h" />
@ -1535,4 +1537,4 @@ xcopy /y /d "$(ProjectDir)\..\src\drivers\win\7z_64.dll" "$(OutDir)"</Command>
</VisualStudio>
</ProjectExtensions>
<!-- ================ UNDUPOBJ ================ -->
</Project>
</Project>