mirror of
https://github.com/wiiu-env/wut.git
synced 2025-01-07 11:38:17 +01:00
wutstdc++: Implement gthread keys.
This commit is contained in:
parent
b4e5bf4106
commit
675549474a
@ -3,6 +3,7 @@ project(wutstdc++ CXX)
|
||||
|
||||
add_library(wutstdc++
|
||||
thread.cc
|
||||
gthread_keys.cc
|
||||
include/bits/gthr-default.h)
|
||||
|
||||
target_compile_definitions(wutstdc++
|
||||
|
98
libraries/wutstdc++/gthread_keys.cc
Normal file
98
libraries/wutstdc++/gthread_keys.cc
Normal file
@ -0,0 +1,98 @@
|
||||
#include "include/bits/gthr-default.h"
|
||||
|
||||
struct gthread_key
|
||||
{
|
||||
bool in_use;
|
||||
void (*dtor) (void *);
|
||||
};
|
||||
|
||||
static gthread_key key_table[__GTHREAD_MAX_KEYS];
|
||||
|
||||
static __gthread_mutex_t key_mutex;
|
||||
static __gthread_once_t init_once_control = __GTHREAD_ONCE_INIT;
|
||||
|
||||
static void init()
|
||||
{
|
||||
__GTHREAD_MUTEX_INIT_FUNCTION(&key_mutex);
|
||||
memset(key_table, 0, sizeof(key_table));
|
||||
}
|
||||
|
||||
int
|
||||
__gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *))
|
||||
{
|
||||
int res = EAGAIN;
|
||||
__gthread_once(&init_once_control, init);
|
||||
__gthread_mutex_lock(&key_mutex);
|
||||
|
||||
for (int i = 0; i < __GTHREAD_MAX_KEYS; ++i) {
|
||||
if (key_table[i].in_use) {
|
||||
continue;
|
||||
}
|
||||
|
||||
key_table[i].in_use = 1;
|
||||
key_table[i].dtor = __dtor;
|
||||
|
||||
res = 0;
|
||||
*__key = (__gthread_key_t)i;
|
||||
break;
|
||||
}
|
||||
|
||||
__gthread_mutex_unlock(&key_mutex);
|
||||
return res;
|
||||
}
|
||||
|
||||
int
|
||||
__gthread_key_delete (__gthread_key_t __key)
|
||||
{
|
||||
__gthread_mutex_lock(&key_mutex);
|
||||
key_table[__key].in_use = 0;
|
||||
key_table[__key].dtor = NULL;
|
||||
__gthread_mutex_unlock(&key_mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const void **
|
||||
__gthread_get_thread_keys()
|
||||
{
|
||||
const void **keys = (const void **)OSGetThreadSpecific(__GTHREAD_THREAD_SPECIFIC_ID);
|
||||
if (!keys) {
|
||||
MEMExpandedHeap *heap = (MEMExpandedHeap *)MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM2);
|
||||
keys = (const void **)MEMAllocFromExpHeapEx(heap, sizeof(void *) * sizeof(__GTHREAD_MAX_KEYS), 4);
|
||||
memset(keys, 0, sizeof(void *) * sizeof(__GTHREAD_MAX_KEYS));
|
||||
OSSetThreadSpecific(__GTHREAD_THREAD_SPECIFIC_ID, keys);
|
||||
}
|
||||
|
||||
return keys;
|
||||
}
|
||||
|
||||
void *
|
||||
__gthread_getspecific (__gthread_key_t __key)
|
||||
{
|
||||
return (void *)__gthread_get_thread_keys()[__key];
|
||||
}
|
||||
|
||||
int
|
||||
__gthread_setspecific (__gthread_key_t __key, const void *__ptr)
|
||||
{
|
||||
__gthread_get_thread_keys()[__key] = __ptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
__gthread_key_cleanup (OSThread *thread)
|
||||
{
|
||||
void **keys = (void **)OSGetThreadSpecific(__GTHREAD_THREAD_SPECIFIC_ID);
|
||||
if (!keys) {
|
||||
return;
|
||||
}
|
||||
|
||||
__gthread_mutex_lock(&key_mutex);
|
||||
|
||||
for (int i = 0; i < __GTHREAD_MAX_KEYS; ++i) {
|
||||
if (key_table[i].in_use && key_table[i].dtor && keys[i]) {
|
||||
key_table[i].dtor(keys[i]);
|
||||
}
|
||||
}
|
||||
|
||||
__gthread_mutex_unlock(&key_mutex);
|
||||
}
|
@ -47,11 +47,10 @@ typedef OSMutex __gthread_mutex_t;
|
||||
typedef OSMutex __gthread_recursive_mutex_t;
|
||||
typedef OSCondition __gthread_cond_t;
|
||||
typedef struct timespec __gthread_time_t;
|
||||
|
||||
// Unimplemented
|
||||
typedef void *__gthread_key_t;
|
||||
typedef uint32_t __gthread_key_t;
|
||||
|
||||
#define __GTHREAD_HAS_COND 1
|
||||
#define __GTHREAD_MAX_KEYS (128)
|
||||
|
||||
#define __GTHREAD_ONCE_VALUE_INIT (0)
|
||||
#define __GTHREAD_ONCE_VALUE_STARTED (1)
|
||||
@ -65,6 +64,8 @@ typedef void *__gthread_key_t;
|
||||
|
||||
#define __GTHREAD_STACK_SIZE (4096*1024)
|
||||
|
||||
#define __GTHREAD_THREAD_SPECIFIC_ID (0)
|
||||
|
||||
static inline int
|
||||
__gthread_active_p (void)
|
||||
{
|
||||
@ -79,6 +80,15 @@ __gthread_thread_deallocator(OSThread *thread, void *stack)
|
||||
MEMFreeToExpHeap(heap, stack);
|
||||
}
|
||||
|
||||
void
|
||||
__gthread_key_cleanup (OSThread *thread);
|
||||
|
||||
static inline void
|
||||
__gthread_thread_cleanup(OSThread *thread, void *stack)
|
||||
{
|
||||
__gthread_key_cleanup(thread);
|
||||
}
|
||||
|
||||
static inline int
|
||||
__gthread_create (__gthread_t *__threadid, void *(*__func) (void*),
|
||||
void *__args)
|
||||
@ -102,6 +112,7 @@ __gthread_create (__gthread_t *__threadid, void *(*__func) (void*),
|
||||
|
||||
*__threadid = thread;
|
||||
OSSetThreadDeallocator(thread, &__gthread_thread_deallocator);
|
||||
OSSetThreadCleanupCallback(thread, &__gthread_thread_cleanup);
|
||||
OSResumeThread(thread);
|
||||
return 0;
|
||||
}
|
||||
@ -163,33 +174,17 @@ __gthread_once (__gthread_once_t *__once, void (*__func) (void))
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
__gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *))
|
||||
{
|
||||
// TODO: Implement __gthread_key_create
|
||||
return -1;
|
||||
}
|
||||
int
|
||||
__gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *));
|
||||
|
||||
static inline int
|
||||
__gthread_key_delete (__gthread_key_t __key)
|
||||
{
|
||||
// TODO: Implement __gthread_key_delete
|
||||
return -1;
|
||||
}
|
||||
int
|
||||
__gthread_key_delete (__gthread_key_t __key);
|
||||
|
||||
static inline void *
|
||||
__gthread_getspecific (__gthread_key_t __key)
|
||||
{
|
||||
// TODO: Implement __gthread_getspecific
|
||||
return NULL;
|
||||
}
|
||||
void *
|
||||
__gthread_getspecific (__gthread_key_t __key);
|
||||
|
||||
static inline int
|
||||
__gthread_setspecific (__gthread_key_t __key, const void *__ptr)
|
||||
{
|
||||
// TODO: Implement __gthread_setspecific
|
||||
return -1;
|
||||
}
|
||||
int
|
||||
__gthread_setspecific (__gthread_key_t __key, const void *__ptr);
|
||||
|
||||
static inline void
|
||||
__gthread_mutex_init_function (__gthread_mutex_t *__mutex)
|
||||
|
Loading…
Reference in New Issue
Block a user