Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement wut_set_thread_specific/wut_get_thread_specific as weak functions #324

Merged
merged 1 commit into from
Jun 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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