mirror of https://github.com/mgba-emu/mgba.git
Util: Refactor TLS out of platform-specific APIs
This commit is contained in:
parent
d02e8a2a87
commit
51c3fca3bf
|
@ -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")
|
||||
|
|
|
@ -24,6 +24,7 @@ typedef THREAD_ENTRY (*ThreadEntry)(void*);
|
|||
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);
|
||||
|
@ -101,6 +102,18 @@ static inline int ThreadSetName(const char* name) {
|
|||
#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
|
||||
|
||||
#endif
|
||||
|
|
|
@ -17,6 +17,7 @@ typedef struct {
|
|||
} 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);
|
||||
|
@ -143,4 +144,19 @@ 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
|
||||
|
|
|
@ -16,6 +16,7 @@ typedef THREAD_ENTRY ThreadEntry(LPVOID);
|
|||
typedef HANDLE Thread;
|
||||
typedef CRITICAL_SECTION Mutex;
|
||||
typedef CONDITION_VARIABLE Condition;
|
||||
typedef DWORD ThreadLocal;
|
||||
|
||||
static inline int MutexInit(Mutex* mutex) {
|
||||
InitializeCriticalSection(mutex);
|
||||
|
@ -88,4 +89,16 @@ static inline int ThreadSetName(const char* 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
|
||||
|
|
|
@ -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 @@ typedef void* Thread;
|
|||
typedef void* Mutex;
|
||||
#endif
|
||||
typedef void* Condition;
|
||||
typedef int ThreadLocal;
|
||||
|
||||
static inline int MutexInit(Mutex* mutex) {
|
||||
UNUSED(mutex);
|
||||
|
@ -93,6 +100,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
|
||||
|
||||
CXX_GUARD_END
|
||||
|
|
|
@ -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 @@ void mCoreThreadStopWaiting(struct mCoreThread* threadContext) {
|
|||
MutexUnlock(&threadContext->impl->stateMutex);
|
||||
}
|
||||
|
||||
struct mCoreThread* mCoreThreadGet(void) {
|
||||
#ifdef USE_PTHREADS
|
||||
struct mCoreThread* mCoreThreadGet(void) {
|
||||
pthread_once(&_contextOnce, _createTLS);
|
||||
return pthread_getspecific(_contextKey);
|
||||
}
|
||||
#elif _WIN32
|
||||
struct mCoreThread* mCoreThreadGet(void) {
|
||||
InitOnceExecuteOnce(&_contextOnce, _createTLS, NULL, 0);
|
||||
return TlsGetValue(_contextKey);
|
||||
}
|
||||
#else
|
||||
struct mCoreThread* mCoreThreadGet(void) {
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
return ThreadLocalGetValue(_contextKey);
|
||||
}
|
||||
|
||||
static void _mCoreLog(struct mLogger* logger, int category, enum mLogLevel level, const char* format, va_list args) {
|
||||
UNUSED(logger);
|
||||
|
|
Loading…
Reference in New Issue