diff --git a/include/mgba/core/log.h b/include/mgba/core/log.h index 9f55ec772..892a8f2f9 100644 --- a/include/mgba/core/log.h +++ b/include/mgba/core/log.h @@ -44,6 +44,9 @@ struct mStandardLogger { struct mLogger* mLogGetContext(void); void mLogSetDefaultLogger(struct mLogger*); +void mLogSetThreadLogger(struct mLogger*); +struct mLogger* mLogGetThreadLogger(void); + int mLogGenerateCategory(const char*, const char*); const char* mLogCategoryName(int); const char* mLogCategoryId(int); diff --git a/include/mgba/core/thread.h b/include/mgba/core/thread.h index fee447ae7..d3d8a9e92 100644 --- a/include/mgba/core/thread.h +++ b/include/mgba/core/thread.h @@ -128,7 +128,6 @@ void mCoreThreadSetRewinding(struct mCoreThread* threadContext, bool); void mCoreThreadRewindParamsChanged(struct mCoreThread* threadContext); struct mCoreThread* mCoreThreadGet(void); -struct mLogger* mCoreThreadLogger(void); CXX_GUARD_END diff --git a/src/core/log.c b/src/core/log.c index 5fe2fe9ee..b897fedb4 100644 --- a/src/core/log.c +++ b/src/core/log.c @@ -6,7 +6,7 @@ #include #include -#include +#include #include #define MAX_CATEGORY 64 @@ -14,11 +14,56 @@ static struct mLogger* _defaultLogger = NULL; -struct mLogger* mLogGetContext(void) { - struct mLogger* logger = NULL; #ifndef DISABLE_THREADING - logger = mCoreThreadLogger(); +static ThreadLocal _contextKey; + +#ifdef USE_PTHREADS +static pthread_once_t _contextOnce = PTHREAD_ONCE_INIT; + +static void _createTLS(void) { + ThreadLocalInitKey(&_contextKey); +} +#elif _WIN32 +static INIT_ONCE _contextOnce = INIT_ONCE_STATIC_INIT; + +static BOOL CALLBACK _createTLS(PINIT_ONCE once, PVOID param, PVOID* context) { + UNUSED(once); + UNUSED(param); + UNUSED(context); + ThreadLocalInitKey(&_contextKey); + return TRUE; +} #endif + +static void _setupTLS(void) { +#ifdef USE_PTHREADS + pthread_once(&_contextOnce, _createTLS); +#elif _WIN32 + InitOnceExecuteOnce(&_contextOnce, _createTLS, NULL, 0); +#endif +} +#endif + +void mLogSetThreadLogger(struct mLogger* logger) { +#ifndef DISABLE_THREADING + _setupTLS(); + ThreadLocalSetKey(_contextKey, logger); +#else + UNUSED(logger); +#endif +} + +struct mLogger* mLogGetThreadLogger(void) { +#ifndef DISABLE_THREADING + _setupTLS(); + return ThreadLocalGetValue(_contextKey); +#else + return NULL; +#endif +} + +struct mLogger* mLogGetContext(void) { + struct mLogger* logger = mLogGetThreadLogger(); if (logger) { return logger; } diff --git a/src/core/thread.c b/src/core/thread.c index 983395c12..903d4b844 100644 --- a/src/core/thread.c +++ b/src/core/thread.c @@ -246,6 +246,8 @@ static THREAD_ENTRY _mCoreThreadRun(void* context) { ThreadLocalSetKey(_contextKey, threadContext); ThreadSetName("CPU Thread"); + mLogSetThreadLogger(&threadContext->logger.d); + #if !defined(_WIN32) && defined(USE_PTHREADS) sigset_t signals; sigemptyset(&signals); @@ -762,12 +764,3 @@ struct mCoreThread* mCoreThreadGet(void) { return NULL; } #endif - -struct mLogger* mCoreThreadLogger(void) { - struct mCoreThread* thread = mCoreThreadGet(); - if (thread) { - return &thread->logger.d; - } - return NULL; -} -