Implement wut_set_thread_specific/wut_get_thread_specific as weak functions

This commit is contained in:
Maschell 2023-06-19 17:08:48 +02:00 committed by fincs
parent 5f42c2c34a
commit 071345feb2
5 changed files with 46 additions and 12 deletions

View File

@ -1,9 +1,10 @@
#include "wut_newlib.h"
#include "wut_thread_specific.h"
#include <stdlib.h>
#include <coreinit/thread.h>
#define __WUT_CONTEXT_THREAD_SPECIFIC_ID OS_THREAD_SPECIFIC_WUT_RESERVED_1
#define __WUT_CONTEXT_THREAD_SPECIFIC_ID WUT_THREAD_SPECIFIC_1
struct __wut_thread_context
{
@ -17,7 +18,7 @@ __wut_thread_cleanup(OSThread *thread,
{
struct __wut_thread_context *context;
context = (struct __wut_thread_context *)OSGetThreadSpecific(__WUT_CONTEXT_THREAD_SPECIFIC_ID);
context = (struct __wut_thread_context *) wut_get_thread_specific(__WUT_CONTEXT_THREAD_SPECIFIC_ID);
if (!context || &context->reent == _GLOBAL_REENT) {
abort();
}
@ -29,11 +30,11 @@ __wut_thread_cleanup(OSThread *thread,
_reclaim_reent(&context->reent);
// Use global reent during free since the current reent is getting freed
OSSetThreadSpecific(__WUT_CONTEXT_THREAD_SPECIFIC_ID, _GLOBAL_REENT);
wut_set_thread_specific(__WUT_CONTEXT_THREAD_SPECIFIC_ID, _GLOBAL_REENT);
free(context);
OSSetThreadSpecific(__WUT_CONTEXT_THREAD_SPECIFIC_ID, NULL);
wut_set_thread_specific(__WUT_CONTEXT_THREAD_SPECIFIC_ID, NULL);
}
struct _reent *
@ -41,21 +42,21 @@ __wut_getreent(void)
{
struct __wut_thread_context *context;
context = (struct __wut_thread_context *)OSGetThreadSpecific(__WUT_CONTEXT_THREAD_SPECIFIC_ID);
context = (struct __wut_thread_context *) wut_get_thread_specific(__WUT_CONTEXT_THREAD_SPECIFIC_ID);
if (!context) {
// Temporarily use global reent during context allocation
OSSetThreadSpecific(__WUT_CONTEXT_THREAD_SPECIFIC_ID, _GLOBAL_REENT);
wut_set_thread_specific(__WUT_CONTEXT_THREAD_SPECIFIC_ID, _GLOBAL_REENT);
context = (struct __wut_thread_context *)malloc(sizeof(*context));
if (!context) {
OSSetThreadSpecific(__WUT_CONTEXT_THREAD_SPECIFIC_ID, NULL);
wut_set_thread_specific(__WUT_CONTEXT_THREAD_SPECIFIC_ID, NULL);
return NULL;
}
_REENT_INIT_PTR(&context->reent);
context->savedCleanup = OSSetThreadCleanupCallback(OSGetCurrentThread(), &__wut_thread_cleanup);
OSSetThreadSpecific(__WUT_CONTEXT_THREAD_SPECIFIC_ID, context);
wut_set_thread_specific(__WUT_CONTEXT_THREAD_SPECIFIC_ID, context);
}
return &context->reent;

View File

@ -0,0 +1,13 @@
#include "wut_thread_specific.h"
#include <coreinit/thread.h>
#include <wut.h>
void __attribute__((weak))
wut_set_thread_specific(__wut_thread_specific_id id, void *value) {
OSSetThreadSpecific(OS_THREAD_SPECIFIC_WUT_RESERVED_0 + id - WUT_THREAD_SPECIFIC_0, value);
}
void *__attribute__((weak))
wut_get_thread_specific(__wut_thread_specific_id id) {
return OSGetThreadSpecific(OS_THREAD_SPECIFIC_WUT_RESERVED_0 + id - WUT_THREAD_SPECIFIC_0);;
}

View File

@ -0,0 +1,18 @@
#pragma once
typedef enum __wut_thread_specific_id {
WUT_THREAD_SPECIFIC_0 = 0,
WUT_THREAD_SPECIFIC_1 = 1,
} __wut_thread_specific_id;
#ifdef __cplusplus
extern "C" {
#endif
void wut_set_thread_specific(__wut_thread_specific_id id, void *value);
void *wut_get_thread_specific(__wut_thread_specific_id id);
#ifdef __cplusplus
}
#endif

View File

@ -6,6 +6,8 @@
#include <coreinit/thread.h>
#include <coreinit/mutex.h>
#include "../wutnewlib/wut_thread_specific.h"
#define __WUT_MAX_KEYS (128)
#define __WUT_STACK_SIZE (128*1024)
@ -13,7 +15,7 @@
#define __WUT_ONCE_VALUE_STARTED (1)
#define __WUT_ONCE_VALUE_DONE (2)
#define __WUT_KEY_THREAD_SPECIFIC_ID OS_THREAD_SPECIFIC_WUT_RESERVED_0
#define __WUT_KEY_THREAD_SPECIFIC_ID WUT_THREAD_SPECIFIC_0
typedef volatile uint32_t __wut_once_t;
typedef struct {

View File

@ -59,7 +59,7 @@ __wut_key_delete(__wut_key_t key)
static const void **
__wut_get_thread_keys()
{
const void **keys = (const void **)OSGetThreadSpecific(__WUT_KEY_THREAD_SPECIFIC_ID);
const void **keys = (const void **)wut_get_thread_specific(__WUT_KEY_THREAD_SPECIFIC_ID);
if (!keys) {
keys = (const void **)malloc(sizeof(void *) * sizeof(__WUT_MAX_KEYS));
if (!keys) {
@ -67,7 +67,7 @@ __wut_get_thread_keys()
}
memset(keys, 0, sizeof(void *) * sizeof(__WUT_MAX_KEYS));
OSSetThreadSpecific(__WUT_KEY_THREAD_SPECIFIC_ID, keys);
wut_set_thread_specific(__WUT_KEY_THREAD_SPECIFIC_ID, keys);
}
return keys;
@ -100,7 +100,7 @@ __wut_setspecific(__wut_key_t key,
void
__wut_key_cleanup(OSThread *thread)
{
void **keys = (void **)OSGetThreadSpecific(__WUT_KEY_THREAD_SPECIFIC_ID);
void **keys = (void **)wut_get_thread_specific(__WUT_KEY_THREAD_SPECIFIC_ID);
if (!keys) {
return;
}