Skip to content

Commit

Permalink
Implement wut_set_thread_specific/wut_get_thread_specific as weak fun…
Browse files Browse the repository at this point in the history
…ctions
  • Loading branch information
Maschell committed Jun 20, 2023
1 parent 5f42c2c commit 328271f
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 12 deletions.
17 changes: 9 additions & 8 deletions libraries/wutnewlib/wut_reent.c
Original file line number Diff line number Diff line change
@@ -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
{
Expand All @@ -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();
}
Expand All @@ -29,33 +30,33 @@ __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 *
__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;
Expand Down
13 changes: 13 additions & 0 deletions libraries/wutnewlib/wut_thread_specific.c
Original file line number Diff line number Diff line change
@@ -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);;
}
18 changes: 18 additions & 0 deletions libraries/wutnewlib/wut_thread_specific.h
Original file line number Diff line number Diff line change
@@ -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
4 changes: 3 additions & 1 deletion libraries/wutstdc++/wut_gthread.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@
#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)

#define __WUT_ONCE_VALUE_INIT (0)
#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 {
Expand Down
6 changes: 3 additions & 3 deletions libraries/wutstdc++/wut_gthread_keys.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,15 @@ __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) {
return NULL;
}

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;
Expand Down Expand Up @@ -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;
}
Expand Down

0 comments on commit 328271f

Please sign in to comment.