From 000fb3b5b37f56746f83d5bd9300785d7422f9d7 Mon Sep 17 00:00:00 2001 From: Maschell Date: Mon, 19 Jun 2023 17:08:48 +0200 Subject: [PATCH] Implement wut_set_thread_specific/wut_get_thread_specific as weak functions --- libraries/wutnewlib/wut_reent.c | 17 ++++++----- libraries/wutnewlib/wut_thread_specific.c | 37 +++++++++++++++++++++++ libraries/wutnewlib/wut_thread_specific.h | 18 +++++++++++ libraries/wutstdc++/wut_gthread.h | 4 ++- libraries/wutstdc++/wut_gthread_keys.cpp | 6 ++-- 5 files changed, 70 insertions(+), 12 deletions(-) create mode 100644 libraries/wutnewlib/wut_thread_specific.c create mode 100644 libraries/wutnewlib/wut_thread_specific.h diff --git a/libraries/wutnewlib/wut_reent.c b/libraries/wutnewlib/wut_reent.c index e58363e4f..285b1e0d1 100644 --- a/libraries/wutnewlib/wut_reent.c +++ b/libraries/wutnewlib/wut_reent.c @@ -1,9 +1,10 @@ #include "wut_newlib.h" +#include "wut_thread_specific.h" #include #include -#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; diff --git a/libraries/wutnewlib/wut_thread_specific.c b/libraries/wutnewlib/wut_thread_specific.c new file mode 100644 index 000000000..8877b1713 --- /dev/null +++ b/libraries/wutnewlib/wut_thread_specific.c @@ -0,0 +1,37 @@ +#include "wut_thread_specific.h" +#include +#include + +void __attribute__((weak)) +wut_set_thread_specific(__wut_thread_specific_id id, void *value) { + OSThread *thread; + asm volatile("lwz %0, -0x20(0)" : "=r" (thread)); // OSGetCurrentThread() + if (thread != NULL) { + if (id == WUT_THREAD_SPECIFIC_0) { + thread->specific[OS_THREAD_SPECIFIC_WUT_RESERVED_0] = value; + } else if (id == WUT_THREAD_SPECIFIC_1) { + thread->specific[OS_THREAD_SPECIFIC_WUT_RESERVED_1] = value; + } else { + WUT_DEBUG_REPORT("wut_set_thread_specific: invalid id (%d)\n", id); + } + } else { + WUT_DEBUG_REPORT("wut_set_thread_specific: invalid thread\n"); + } +} + +void *__attribute__((weak)) +wut_get_thread_specific(__wut_thread_specific_id id) { + OSThread *thread; + asm volatile("lwz %0, -0x20(0)" : "=r" (thread)); // OSGetCurrentThread() + if (thread != NULL) { + if (id == WUT_THREAD_SPECIFIC_0) { + return thread->specific[OS_THREAD_SPECIFIC_WUT_RESERVED_0]; + } else if (id == WUT_THREAD_SPECIFIC_1) { + return thread->specific[OS_THREAD_SPECIFIC_WUT_RESERVED_1]; + } + WUT_DEBUG_REPORT("wut_get_thread_specific: invalid id (%d)\n", id); + } else { + WUT_DEBUG_REPORT("wut_get_thread_specific: invalid thread\n"); + } + return NULL; +} \ No newline at end of file diff --git a/libraries/wutnewlib/wut_thread_specific.h b/libraries/wutnewlib/wut_thread_specific.h new file mode 100644 index 000000000..c84188f4a --- /dev/null +++ b/libraries/wutnewlib/wut_thread_specific.h @@ -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 diff --git a/libraries/wutstdc++/wut_gthread.h b/libraries/wutstdc++/wut_gthread.h index e422fdb11..5320e8df9 100644 --- a/libraries/wutstdc++/wut_gthread.h +++ b/libraries/wutstdc++/wut_gthread.h @@ -6,6 +6,8 @@ #include #include +#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 { diff --git a/libraries/wutstdc++/wut_gthread_keys.cpp b/libraries/wutstdc++/wut_gthread_keys.cpp index 7ea5cda62..0848615bb 100644 --- a/libraries/wutstdc++/wut_gthread_keys.cpp +++ b/libraries/wutstdc++/wut_gthread_keys.cpp @@ -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; }