Implement __syscall_getreent (#318)

This commit is contained in:
GaryOderNichts
2023-05-21 15:03:48 +02:00
committed by GitHub
parent 1a85382b17
commit 3ae38b15c7
5 changed files with 95 additions and 6 deletions

View File

@@ -52,6 +52,28 @@ typedef int (*OSThreadEntryPointFn)(int argc, const char **argv);
typedef void (*OSThreadCleanupCallbackFn)(OSThread *thread, void *stack);
typedef void (*OSThreadDeallocatorFn)(OSThread *thread, void *stack);
typedef enum OSThreadSpecificID
{
//! These can be used by applications
OS_THREAD_SPECIFIC_0 = 0,
OS_THREAD_SPECIFIC_1 = 1,
OS_THREAD_SPECIFIC_2 = 2,
OS_THREAD_SPECIFIC_3 = 3,
OS_THREAD_SPECIFIC_4 = 4,
OS_THREAD_SPECIFIC_5 = 5,
OS_THREAD_SPECIFIC_6 = 6,
OS_THREAD_SPECIFIC_7 = 7,
OS_THREAD_SPECIFIC_8 = 8,
OS_THREAD_SPECIFIC_9 = 9,
OS_THREAD_SPECIFIC_10 = 10,
OS_THREAD_SPECIFIC_11 = 11,
OS_THREAD_SPECIFIC_12 = 12,
OS_THREAD_SPECIFIC_13 = 13,
//! These are reserved to wut for internal use
OS_THREAD_SPECIFIC_WUT_RESERVED_0 = 14,
OS_THREAD_SPECIFIC_WUT_RESERVED_1 = 15,
} OSThreadSpecificID;
enum OS_THREAD_STATE
{
OS_THREAD_STATE_NONE = 0,
@@ -100,9 +122,9 @@ enum OS_THREAD_ATTRIB
};
enum OS_THREAD_TYPE {
OS_THREAD_TYPE_DRIVER = 0,
OS_THREAD_TYPE_IO = 1,
OS_THREAD_TYPE_APP = 2
OS_THREAD_TYPE_DRIVER = 0,
OS_THREAD_TYPE_IO = 1,
OS_THREAD_TYPE_APP = 2
};
struct OSMutexQueue
@@ -390,7 +412,7 @@ OSGetThreadPriority(OSThread *thread);
* Get a thread's specific value set by OSSetThreadSpecific.
*/
void *
OSGetThreadSpecific(uint32_t id);
OSGetThreadSpecific(OSThreadSpecificID id);
/**
@@ -511,7 +533,7 @@ OSSetThreadRunQuantum(OSThread *thread,
* Can be read with OSGetThreadSpecific.
*/
void
OSSetThreadSpecific(uint32_t id,
OSSetThreadSpecific(OSThreadSpecificID id,
void *value);

View File

@@ -47,6 +47,10 @@ void __syscall_malloc_unlock(struct _reent *ptr) {
return __wut_malloc_unlock(ptr);
}
struct _reent *__syscall_getreent(void) {
return __wut_getreent();
}
void __syscall_exit(int rc) {
__fini_wut();
__wut_exit(rc);

View File

@@ -19,6 +19,7 @@ int __wut_clock_gettime(clockid_t clock_id, struct timespec *tp);
int __wut_clock_settime(clockid_t clock_id, const struct timespec *tp);
int __wut_clock_getres(clockid_t clock_id, struct timespec *res);
int __wut_nanosleep(const struct timespec *req, struct timespec *rem);
struct _reent *__wut_getreent(void);
void __init_wut_malloc_lock();
void __init_wut_sbrk_heap();

View File

@@ -0,0 +1,62 @@
#include "wut_newlib.h"
#include <stdlib.h>
#include <coreinit/thread.h>
#define __WUT_CONTEXT_THREAD_SPECIFIC_ID OS_THREAD_SPECIFIC_WUT_RESERVED_1
struct __wut_thread_context
{
struct _reent reent;
OSThreadCleanupCallbackFn savedCleanup;
};
static void
__wut_thread_cleanup(OSThread *thread,
void *stack)
{
struct __wut_thread_context *context;
context = (struct __wut_thread_context *)OSGetThreadSpecific(__WUT_CONTEXT_THREAD_SPECIFIC_ID);
if (!context || &context->reent == _GLOBAL_REENT) {
abort();
}
if (context->savedCleanup) {
context->savedCleanup(thread, stack);
}
_reclaim_reent(&context->reent);
// Use global reent during free since the current reent is getting freed
OSSetThreadSpecific(__WUT_CONTEXT_THREAD_SPECIFIC_ID, _GLOBAL_REENT);
free(context);
OSSetThreadSpecific(__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);
if (!context) {
// Temporarily use global reent during context allocation
OSSetThreadSpecific(__WUT_CONTEXT_THREAD_SPECIFIC_ID, _GLOBAL_REENT);
context = (struct __wut_thread_context *)malloc(sizeof(*context));
if (!context) {
OSSetThreadSpecific(__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);
}
return &context->reent;
}

View File

@@ -13,7 +13,7 @@
#define __WUT_ONCE_VALUE_STARTED (1)
#define __WUT_ONCE_VALUE_DONE (2)
#define __WUT_KEY_THREAD_SPECIFIC_ID (0)
#define __WUT_KEY_THREAD_SPECIFIC_ID OS_THREAD_SPECIFIC_WUT_RESERVED_0
typedef volatile uint32_t __wut_once_t;
typedef struct {