Util: Refactor TLS out of platform-specific APIs
Vicki Pfau vi@endrift.com
Sun, 12 Jul 2020 16:57:09 -0700
6 files changed,
71 insertions(+),
17 deletions(-)
M
CMakeLists.txt
→
CMakeLists.txt
@@ -13,7 +13,7 @@ set(CMAKE_C_STANDARD 99)
if(NOT MSVC) set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_C_EXTENSIONS OFF) - if(SWITCH) + if(SWITCH OR 3DS) set(CMAKE_C_STANDARD 11) set(CMAKE_C_EXTENSIONS ON) elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_LESS "4.3")
M
include/mgba-util/platform/posix/threading.h
→
include/mgba-util/platform/posix/threading.h
@@ -24,6 +24,7 @@
typedef pthread_t Thread; typedef pthread_mutex_t Mutex; typedef pthread_cond_t Condition; +typedef pthread_key_t ThreadLocal; static inline int MutexInit(Mutex* mutex) { return pthread_mutex_init(mutex, 0);@@ -99,6 +100,18 @@ #else
UNUSED(name); return 0; #endif +} + +static inline void ThreadLocalInitKey(ThreadLocal* key) { + pthread_key_create(key, 0); +} + +static inline void ThreadLocalSetKey(ThreadLocal key, void* value) { + pthread_setspecific(key, value); +} + +static inline void* ThreadLocalGetValue(ThreadLocal key) { + return pthread_getspecific(key); } CXX_GUARD_END
M
include/mgba-util/platform/psp2/threading.h
→
include/mgba-util/platform/psp2/threading.h
@@ -17,6 +17,7 @@ int waiting;
} Condition; #define THREAD_ENTRY int typedef THREAD_ENTRY (*ThreadEntry)(void*); +typedef int ThreadLocal; static inline int MutexInit(Mutex* mutex) { Mutex id = sceKernelCreateMutex("mutex", 0, 0, 0);@@ -142,5 +143,20 @@
static inline int ThreadSetName(const char* name) { UNUSED(name); return -1; +} + +static inline void ThreadLocalInitKey(ThreadLocal* key) { + static int base = 0x90; + *key = __atomic_fetch_add(&base, 1, __ATOMIC_SEQ_CST); +} + +static inline void ThreadLocalSetKey(ThreadLocal key, void* value) { + void** tls = sceKernelGetTLSAddr(key); + *tls = value; +} + +static inline void* ThreadLocalGetValue(ThreadLocal key) { + void** tls = sceKernelGetTLSAddr(key); + return *tls; } #endif
M
include/mgba-util/platform/windows/threading.h
→
include/mgba-util/platform/windows/threading.h
@@ -16,6 +16,7 @@
typedef HANDLE Thread; typedef CRITICAL_SECTION Mutex; typedef CONDITION_VARIABLE Condition; +typedef DWORD ThreadLocal; static inline int MutexInit(Mutex* mutex) { InitializeCriticalSection(mutex);@@ -86,6 +87,18 @@
static inline int ThreadSetName(const char* name) { UNUSED(name); return -1; +} + +static inline void ThreadLocalInitKey(ThreadLocal* key) { + *key = TlsAlloc(); +} + +static inline void ThreadLocalSetKey(ThreadLocal key, void* value) { + TlsSetValue(key, value); +} + +static inline void* ThreadLocalGetValue(ThreadLocal key) { + return TlsGetValue(key); } #endif
M
include/mgba-util/threading.h
→
include/mgba-util/threading.h
@@ -11,6 +11,12 @@
CXX_GUARD_START #ifndef DISABLE_THREADING +#if __STDC_VERSION__ >= 201112L +#define ThreadLocal _Thread_local void* +#define ThreadLocalInitKey(X) +#define ThreadLocalSetKey(K, V) K = V +#define ThreadLocalGetValue(K) K +#endif #ifdef USE_PTHREADS #include <mgba-util/platform/posix/threading.h> #elif defined(_WIN32)@@ -40,6 +46,7 @@ #else
typedef void* Mutex; #endif typedef void* Condition; +typedef int ThreadLocal; static inline int MutexInit(Mutex* mutex) { UNUSED(mutex);@@ -92,6 +99,20 @@
static inline int ConditionWake(Condition* cond) { UNUSED(cond); return 0; +} + +static inline void ThreadLocalInitKey(ThreadLocal* key) { + UNUSED(key); +} + +static inline void ThreadLocalSetKey(ThreadLocal key, void* value) { + UNUSED(key); + UNUSED(value); +} + +static inline void* ThreadLocalGetValue(ThreadLocal key) { + UNUSED(key); + return NULL; } #endif
M
src/core/thread.c
→
src/core/thread.c
@@ -16,23 +16,22 @@
#ifndef DISABLE_THREADING static const float _defaultFPSTarget = 60.f; +static ThreadLocal _contextKey; #ifdef USE_PTHREADS -static pthread_key_t _contextKey; static pthread_once_t _contextOnce = PTHREAD_ONCE_INIT; static void _createTLS(void) { - pthread_key_create(&_contextKey, 0); + ThreadLocalInitKey(&_contextKey); } #elif _WIN32 -static DWORD _contextKey; 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); - _contextKey = TlsAlloc(); + ThreadLocalInitKey(&_contextKey); return TRUE; } #endif@@ -144,12 +143,11 @@ static THREAD_ENTRY _mCoreThreadRun(void* context) {
struct mCoreThread* threadContext = context; #ifdef USE_PTHREADS pthread_once(&_contextOnce, _createTLS); - pthread_setspecific(_contextKey, threadContext); #elif _WIN32 InitOnceExecuteOnce(&_contextOnce, _createTLS, NULL, 0); - TlsSetValue(_contextKey, threadContext); #endif + ThreadLocalSetKey(_contextKey, threadContext); ThreadSetName("CPU Thread"); #if !defined(_WIN32) && defined(USE_PTHREADS)@@ -620,21 +618,14 @@ }
MutexUnlock(&threadContext->impl->stateMutex); } -#ifdef USE_PTHREADS struct mCoreThread* mCoreThreadGet(void) { +#ifdef USE_PTHREADS pthread_once(&_contextOnce, _createTLS); - return pthread_getspecific(_contextKey); -} #elif _WIN32 -struct mCoreThread* mCoreThreadGet(void) { InitOnceExecuteOnce(&_contextOnce, _createTLS, NULL, 0); - return TlsGetValue(_contextKey); +#endif + return ThreadLocalGetValue(_contextKey); } -#else -struct mCoreThread* mCoreThreadGet(void) { - return NULL; -} -#endif static void _mCoreLog(struct mLogger* logger, int category, enum mLogLevel level, const char* format, va_list args) { UNUSED(logger);