From 9405c809e0911f2467cd44611ad80d37509c65aa Mon Sep 17 00:00:00 2001 From: Ilari Liusvaara Date: Sun, 4 Mar 2012 15:41:06 +0200 Subject: [PATCH] Debug multithreading-related errors --- Makefile | 8 +++- include/core/controllerframe.hpp | 1 + include/core/threaddebug.hpp | 14 +++++++ src/core/misc.cpp | 2 + src/core/threaddebug.cpp | 91 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 include/core/threaddebug.hpp create mode 100644 src/core/threaddebug.cpp diff --git a/Makefile b/Makefile index 86fd2b3f..df2234a5 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ HOSTCC = $(CC) #Flags. HOSTCCFLAGS = -std=gnu++0x CFLAGS = -I$(BSNES_PATH) -Iinclude -Iavi -std=gnu++0x -LDFLAGS = -lboost_iostreams -lboost_filesystem -lboost_system -lboost_regex -lz +LDFLAGS = -lboost_iostreams-mt -lboost_filesystem-mt -lboost_system-mt -lboost_regex-mt -lz PLATFORM_CFLAGS = PLATFORM_LDFLAGS = @@ -32,6 +32,12 @@ all: $(PROGRAMS) #Platform objects. PLATFORM_OBJECTS= +#malloc threadsafety +ifdef MAKE_MALLOC_THREADSAFE +CFLAGS += -DMAKE_MALLOC_THREADSAFE +LDFLAGS += -Wl,--wrap,malloc,--wrap,calloc,--wrap,realloc,--wrap,free +endif + #Lua. ifndef LUA CFLAGS += -DNO_LUA diff --git a/include/core/controllerframe.hpp b/include/core/controllerframe.hpp index ef3e60c4..85ee81eb 100644 --- a/include/core/controllerframe.hpp +++ b/include/core/controllerframe.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include diff --git a/include/core/threaddebug.hpp b/include/core/threaddebug.hpp new file mode 100644 index 00000000..95af467e --- /dev/null +++ b/include/core/threaddebug.hpp @@ -0,0 +1,14 @@ +#ifndef _threaddebug__hpp__included__ +#define _threaddebug__hpp__included__ + +#define THREAD_OTHER -1 +#define THREAD_MAIN -2 +#define THREAD_EMULATION 0 +#define THREAD_UI 1 +#define THREAD_JOYSTICK 2 + +void assert_thread(signed shouldbe); +void mark_thread_as(signed call_me); +void init_threaded_malloc(); + +#endif \ No newline at end of file diff --git a/src/core/misc.cpp b/src/core/misc.cpp index dceaf71a..d306beb1 100644 --- a/src/core/misc.cpp +++ b/src/core/misc.cpp @@ -3,6 +3,7 @@ #include "core/memorymanip.hpp" #include "core/misc.hpp" #include "core/rom.hpp" +#include "core/threaddebug.hpp" #include "core/window.hpp" #include @@ -315,6 +316,7 @@ bool in_global_ctors() void reached_main() { reached_main_flag = true; + init_threaded_malloc(); } std::string bsnes_core_version; diff --git a/src/core/threaddebug.cpp b/src/core/threaddebug.cpp new file mode 100644 index 00000000..015c4340 --- /dev/null +++ b/src/core/threaddebug.cpp @@ -0,0 +1,91 @@ +#include "core/threaddebug.hpp" +#include "core/window.hpp" + +#define DESIGNATED_THREADS 16 + +namespace +{ + volatile thread_id* threads[DESIGNATED_THREADS]; + volatile bool thread_marked; + mutex* malloc_mutex; +} + +void assert_thread(signed shouldbe, const std::string& desc) +{ +#ifndef DISABLE_THREAD_ASSERTIONS + if(shouldbe < 0 || shouldbe >= DESIGNATED_THREADS) { + std::cerr << "WARNING: assert_thread(" << shouldbe << ") called." << std::endl; + return; + } + if(!thread_marked) + return; + thread_id* t = const_cast(threads[shouldbe]); + if(!t || !t->is_me()) + std::cerr << "WARNING: " << desc << ": Wrong thread!" << std::endl; +#endif +} + +void mark_thread_as(signed call_me) +{ +#ifndef DISABLE_THREAD_ASSERTIONS + if(call_me < 0 || call_me >= DESIGNATED_THREADS) { + std::cerr << "WARNING: mark_thread_as(" << call_me << ") called." << std::endl; + return; + } + thread_marked = true; + threads[call_me] = &thread_id::me(); +#endif +} + +#ifdef MAKE_MALLOC_THREADSAFE +void init_threaded_malloc() +{ + if(!malloc_mutex) + malloc_mutex = &mutex::aquire(); +} + +extern "C" +{ + +void* __real_malloc(size_t); +void* __real_calloc(size_t, size_t); +void* __real_realloc(void*, size_t); +void __real_free(void*); + +void* __wrap_malloc(size_t block) +{ + if(!malloc_mutex) + return __real_malloc(block); + mutex::holder(*malloc_mutex); + return __real_malloc(block); +} + +void* __wrap_calloc(size_t count, size_t size) +{ + if(!malloc_mutex) + return __real_calloc(count, size); + mutex::holder(*malloc_mutex); + return __real_calloc(count, size); +} + +void* __wrap_realloc(void* block, size_t size) +{ + if(!malloc_mutex) + return __real_realloc(block, size); + mutex::holder(*malloc_mutex); + return __real_realloc(block, size); +} + +void __wrap_free(void* block) +{ + if(!malloc_mutex) + return __real_free(block); + mutex::holder(*malloc_mutex); + return __real_free(block); +} +} +#else +void init_threaded_malloc() +{ +} +#endif -- 2.11.4.GIT