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:
parent
5cec622e58
commit
d32ab0ad51
|
@ -502,6 +502,7 @@ set(SRC_CORE
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/utils/guid.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/utils/guid.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/utils/md5.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/utils/md5.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/utils/memory.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/utils/memory.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/utils/mutex.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -215,16 +215,23 @@ void debugSymbolPage_t::print(void)
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
debugSymbolTable_t::debugSymbolTable_t(void)
|
debugSymbolTable_t::debugSymbolTable_t(void)
|
||||||
{
|
{
|
||||||
|
cs = new FCEU::mutex();
|
||||||
}
|
}
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
debugSymbolTable_t::~debugSymbolTable_t(void)
|
debugSymbolTable_t::~debugSymbolTable_t(void)
|
||||||
{
|
{
|
||||||
this->clear();
|
this->clear();
|
||||||
|
|
||||||
|
if (cs)
|
||||||
|
{
|
||||||
|
delete cs;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
void debugSymbolTable_t::clear(void)
|
void debugSymbolTable_t::clear(void)
|
||||||
{
|
{
|
||||||
|
FCEU::autoScopedLock alock(cs);
|
||||||
|
|
||||||
std::map <int, debugSymbolPage_t*>::iterator it;
|
std::map <int, debugSymbolPage_t*>::iterator it;
|
||||||
|
|
||||||
for (it=pageMap.begin(); it!=pageMap.end(); it++)
|
for (it=pageMap.begin(); it!=pageMap.end(); it++)
|
||||||
|
@ -305,6 +312,7 @@ int debugSymbolTable_t::loadFileNL( int bank )
|
||||||
char stmp[512], line[512];
|
char stmp[512], line[512];
|
||||||
debugSymbolPage_t *page = NULL;
|
debugSymbolPage_t *page = NULL;
|
||||||
debugSymbol_t *sym = NULL;
|
debugSymbol_t *sym = NULL;
|
||||||
|
FCEU::autoScopedLock alock(cs);
|
||||||
|
|
||||||
//printf("Looking to Load Debug Bank: $%X \n", bank );
|
//printf("Looking to Load Debug Bank: $%X \n", bank );
|
||||||
|
|
||||||
|
@ -544,6 +552,7 @@ int debugSymbolTable_t::loadFileNL( int bank )
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
int debugSymbolTable_t::loadRegisterMap(void)
|
int debugSymbolTable_t::loadRegisterMap(void)
|
||||||
{
|
{
|
||||||
|
FCEU::autoScopedLock alock(cs);
|
||||||
debugSymbolPage_t *page;
|
debugSymbolPage_t *page;
|
||||||
|
|
||||||
page = new debugSymbolPage_t();
|
page = new debugSymbolPage_t();
|
||||||
|
@ -627,6 +636,7 @@ int debugSymbolTable_t::addSymbolAtBankOffset( int bank, int ofs, debugSymbol_t
|
||||||
{
|
{
|
||||||
debugSymbolPage_t *page;
|
debugSymbolPage_t *page;
|
||||||
std::map <int, debugSymbolPage_t*>::iterator it;
|
std::map <int, debugSymbolPage_t*>::iterator it;
|
||||||
|
FCEU::autoScopedLock alock(cs);
|
||||||
|
|
||||||
it = pageMap.find( bank );
|
it = pageMap.find( bank );
|
||||||
|
|
||||||
|
@ -649,6 +659,7 @@ int debugSymbolTable_t::deleteSymbolAtBankOffset( int bank, int ofs )
|
||||||
{
|
{
|
||||||
debugSymbolPage_t *page;
|
debugSymbolPage_t *page;
|
||||||
std::map <int, debugSymbolPage_t*>::iterator it;
|
std::map <int, debugSymbolPage_t*>::iterator it;
|
||||||
|
FCEU::autoScopedLock alock(cs);
|
||||||
|
|
||||||
it = pageMap.find( bank );
|
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 )
|
debugSymbol_t *debugSymbolTable_t::getSymbolAtBankOffset( int bank, int ofs )
|
||||||
{
|
{
|
||||||
|
FCEU::autoScopedLock alock(cs);
|
||||||
|
|
||||||
auto it = pageMap.find( bank );
|
auto it = pageMap.find( bank );
|
||||||
|
|
||||||
return it != pageMap.end() ? it->second->getSymbolAtOffset( ofs ) : NULL;
|
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 )
|
debugSymbol_t *debugSymbolTable_t::getSymbol( int bank, const std::string &name )
|
||||||
{
|
{
|
||||||
|
FCEU::autoScopedLock alock(cs);
|
||||||
|
|
||||||
auto it = pageMap.find( bank );
|
auto it = pageMap.find( bank );
|
||||||
|
|
||||||
return it != pageMap.end() ? it->second->getSymbol( name ) : NULL;
|
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 )
|
debugSymbol_t *debugSymbolTable_t::getSymbolAtAnyBank( const std::string &name )
|
||||||
{
|
{
|
||||||
|
FCEU::autoScopedLock alock(cs);
|
||||||
|
|
||||||
for (auto &page : pageMap)
|
for (auto &page : pageMap)
|
||||||
{
|
{
|
||||||
auto sym = getSymbol( page.first, name );
|
auto sym = getSymbol( page.first, name );
|
||||||
|
@ -697,6 +714,7 @@ void debugSymbolTable_t::save(void)
|
||||||
{
|
{
|
||||||
debugSymbolPage_t *page;
|
debugSymbolPage_t *page;
|
||||||
std::map <int, debugSymbolPage_t*>::iterator it;
|
std::map <int, debugSymbolPage_t*>::iterator it;
|
||||||
|
FCEU::autoScopedLock alock(cs);
|
||||||
|
|
||||||
for (it=pageMap.begin(); it!=pageMap.end(); it++)
|
for (it=pageMap.begin(); it!=pageMap.end(); it++)
|
||||||
{
|
{
|
||||||
|
@ -710,6 +728,7 @@ void debugSymbolTable_t::print(void)
|
||||||
{
|
{
|
||||||
debugSymbolPage_t *page;
|
debugSymbolPage_t *page;
|
||||||
std::map <int, debugSymbolPage_t*>::iterator it;
|
std::map <int, debugSymbolPage_t*>::iterator it;
|
||||||
|
FCEU::autoScopedLock alock(cs);
|
||||||
|
|
||||||
for (it=pageMap.begin(); it!=pageMap.end(); it++)
|
for (it=pageMap.begin(); it!=pageMap.end(); it++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
#include "utils/mutex.h"
|
||||||
|
|
||||||
struct debugSymbol_t
|
struct debugSymbol_t
|
||||||
{
|
{
|
||||||
int ofs;
|
int ofs;
|
||||||
|
@ -103,6 +105,7 @@ class debugSymbolTable_t
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map <int, debugSymbolPage_t*> pageMap;
|
std::map <int, debugSymbolPage_t*> pageMap;
|
||||||
|
FCEU::mutex *cs;
|
||||||
|
|
||||||
int loadRegisterMap(void);
|
int loadRegisterMap(void);
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
|
@ -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;
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
|
@ -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\ioapi.cpp" />
|
||||||
<ClCompile Include="..\src\utils\md5.cpp" />
|
<ClCompile Include="..\src\utils\md5.cpp" />
|
||||||
<ClCompile Include="..\src\utils\memory.cpp" />
|
<ClCompile Include="..\src\utils\memory.cpp" />
|
||||||
|
<ClCompile Include="..\src\utils\mutex.cpp" />
|
||||||
<ClCompile Include="..\src\utils\unzip.cpp" />
|
<ClCompile Include="..\src\utils\unzip.cpp" />
|
||||||
<ClCompile Include="..\src\utils\xstring.cpp" />
|
<ClCompile Include="..\src\utils\xstring.cpp" />
|
||||||
<ClCompile Include="..\src\lua\src\lapi.c">
|
<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\ioapi.h" />
|
||||||
<ClInclude Include="..\src\utils\md5.h" />
|
<ClInclude Include="..\src\utils\md5.h" />
|
||||||
<ClInclude Include="..\src\utils\memory.h" />
|
<ClInclude Include="..\src\utils\memory.h" />
|
||||||
|
<ClInclude Include="..\src\utils\mutex.h" />
|
||||||
<ClInclude Include="..\src\utils\unzip.h" />
|
<ClInclude Include="..\src\utils\unzip.h" />
|
||||||
<ClInclude Include="..\src\utils\valuearray.h" />
|
<ClInclude Include="..\src\utils\valuearray.h" />
|
||||||
<ClInclude Include="..\src\utils\xstring.h" />
|
<ClInclude Include="..\src\utils\xstring.h" />
|
||||||
|
|
Loading…
Reference in New Issue