mirror of
https://github.com/devkitPro/wut.git
synced 2026-08-27 21:34:43 -05:00
Implement __syscall_getreent (#318)
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
62
libraries/wutnewlib/wut_reent.c
Normal file
62
libraries/wutnewlib/wut_reent.c
Normal 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;
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user