From d3bd9a2ce91d22c7e4201215be39724535089f70 Mon Sep 17 00:00:00 2001 From: fincs Date: Tue, 6 Jan 2026 19:20:46 +0100 Subject: [PATCH 1/2] wutnewlib: implement new unified threading syscalls (replaces wutstdc++) --- Makefile | 1 - libraries/wutcrt/wut_crt.c | 6 - libraries/wutcrt/wut_preinit.c | 4 +- libraries/wutnewlib/wut_lock.c | 80 ----- libraries/wutnewlib/wut_malloc_lock.c | 23 -- libraries/wutnewlib/wut_newlib.c | 59 ---- libraries/wutnewlib/wut_newlib.h | 17 +- libraries/wutnewlib/wut_thread.c | 287 ++++++++++++++++++ libraries/wutstdc++/wut_gthread.cpp | 197 ------------ libraries/wutstdc++/wut_gthread.h | 128 -------- libraries/wutstdc++/wut_gthread_cond.cpp | 97 ------ libraries/wutstdc++/wut_gthread_keys.cpp | 119 -------- libraries/wutstdc++/wut_gthread_mutex.cpp | 37 --- libraries/wutstdc++/wut_gthread_once.cpp | 23 -- .../wutstdc++/wut_gthread_recursive_mutex.cpp | 38 --- libraries/wutstdc++/wut_gthread_thread.cpp | 102 ------- 16 files changed, 294 insertions(+), 924 deletions(-) delete mode 100644 libraries/wutnewlib/wut_lock.c delete mode 100644 libraries/wutnewlib/wut_malloc_lock.c create mode 100644 libraries/wutnewlib/wut_thread.c delete mode 100644 libraries/wutstdc++/wut_gthread.cpp delete mode 100644 libraries/wutstdc++/wut_gthread.h delete mode 100644 libraries/wutstdc++/wut_gthread_cond.cpp delete mode 100644 libraries/wutstdc++/wut_gthread_keys.cpp delete mode 100644 libraries/wutstdc++/wut_gthread_mutex.cpp delete mode 100644 libraries/wutstdc++/wut_gthread_once.cpp delete mode 100644 libraries/wutstdc++/wut_gthread_recursive_mutex.cpp delete mode 100644 libraries/wutstdc++/wut_gthread_thread.cpp diff --git a/Makefile b/Makefile index 068f6b785..03fd7744f 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,6 @@ TARGET := wut SOURCES := cafe \ libraries/wutcrt \ libraries/wutnewlib \ - libraries/wutstdc++ \ libraries/wutmalloc \ libraries/wutdevoptab \ libraries/wutsocket \ diff --git a/libraries/wutcrt/wut_crt.c b/libraries/wutcrt/wut_crt.c index 6f597fed6..1dd6326c3 100644 --- a/libraries/wutcrt/wut_crt.c +++ b/libraries/wutcrt/wut_crt.c @@ -2,8 +2,6 @@ void __init_wut_newlib(); void -__init_wut_stdcpp(); -void __init_wut_devoptab(); void __attribute__((weak)) __init_wut_socket(); @@ -11,8 +9,6 @@ __init_wut_socket(); void __fini_wut_newlib(); void -__fini_wut_stdcpp(); -void __fini_wut_devoptab(); void __attribute__((weak)) __fini_wut_socket(); @@ -21,7 +17,6 @@ void __attribute__((weak)) __init_wut() { __init_wut_newlib(); - __init_wut_stdcpp(); __init_wut_devoptab(); if (&__init_wut_socket) __init_wut_socket(); } @@ -31,6 +26,5 @@ __fini_wut() { if (&__fini_wut_socket) __fini_wut_socket(); __fini_wut_devoptab(); - __fini_wut_stdcpp(); __fini_wut_newlib(); } diff --git a/libraries/wutcrt/wut_preinit.c b/libraries/wutcrt/wut_preinit.c index 380d7c640..8559354ae 100644 --- a/libraries/wutcrt/wut_preinit.c +++ b/libraries/wutcrt/wut_preinit.c @@ -3,7 +3,7 @@ void __init_wut_sbrk_heap(MEMHeapHandle heapHandle); void -__init_wut_malloc_lock(); +__init_wut_thread(); void __init_wut_defaultheap(); @@ -13,6 +13,6 @@ __preinit_user(MEMHeapHandle *mem1, MEMHeapHandle *mem2) { __init_wut_sbrk_heap(*mem2); - __init_wut_malloc_lock(); + __init_wut_thread(); __init_wut_defaultheap(); } diff --git a/libraries/wutnewlib/wut_lock.c b/libraries/wutnewlib/wut_lock.c deleted file mode 100644 index 93377f2aa..000000000 --- a/libraries/wutnewlib/wut_lock.c +++ /dev/null @@ -1,80 +0,0 @@ -#include "wut_newlib.h" - -#include -#include - -#define MAX_LOCKS 16 - -static OSMutex sLibcLocks[MAX_LOCKS]; -static volatile uint32_t sLibcLockUsedMask = 0; - -static inline bool -__wut_is_lock_valid(int *lock) -{ - return lock && *lock >= 0 && *lock < MAX_LOCKS; -} - -int -__wut_lock_init(int *lock, - int recursive) -{ - if (!lock) { - return -1; - } - - int slot; - uint32_t new_mask; - uint32_t cur_mask = sLibcLockUsedMask; - do { - slot = __builtin_ffs(~cur_mask) - 1; - if (slot < 0 || slot >= MAX_LOCKS) break; - new_mask = cur_mask | (1U << slot); - } while (!OSCompareAndSwapAtomicEx(&sLibcLockUsedMask, cur_mask, new_mask, &cur_mask)); - - if (slot < 0 || slot >= MAX_LOCKS) { - return -1; - } - - *lock = slot; - OSInitMutex(&sLibcLocks[*lock]); - return 0; -} - -int -__wut_lock_close(int *lock) -{ - if (!__wut_is_lock_valid(lock)) { - return -1; - } - - uint32_t new_mask; - uint32_t cur_mask = sLibcLockUsedMask; - do { - new_mask = cur_mask & ~(1U << *lock); - } while (!OSCompareAndSwapAtomicEx(&sLibcLockUsedMask, cur_mask, new_mask, &cur_mask)); - - *lock = -1; - return 0; -} - -int -__wut_lock_acquire(int *lock) -{ - if (!__wut_is_lock_valid(lock)) { - return -1; - } - - OSLockMutex(&sLibcLocks[*lock]); - return 0; -} - -int -__wut_lock_release(int *lock) -{ - if (!__wut_is_lock_valid(lock)) { - return -1; - } - - OSUnlockMutex(&sLibcLocks[*lock]); - return 0; -} diff --git a/libraries/wutnewlib/wut_malloc_lock.c b/libraries/wutnewlib/wut_malloc_lock.c deleted file mode 100644 index 546ea3a33..000000000 --- a/libraries/wutnewlib/wut_malloc_lock.c +++ /dev/null @@ -1,23 +0,0 @@ -#include "wut_newlib.h" - -#include - -static OSSpinLock sMallocSpinLock; - -void -__wut_malloc_lock(struct _reent *r) -{ - OSUninterruptibleSpinLock_Acquire(&sMallocSpinLock); -} - -void -__wut_malloc_unlock(struct _reent *r) -{ - OSUninterruptibleSpinLock_Release(&sMallocSpinLock); -} - -void -__init_wut_malloc_lock() -{ - OSInitSpinLock(&sMallocSpinLock); -} diff --git a/libraries/wutnewlib/wut_newlib.c b/libraries/wutnewlib/wut_newlib.c index 889d4a270..746584df2 100644 --- a/libraries/wutnewlib/wut_newlib.c +++ b/libraries/wutnewlib/wut_newlib.c @@ -71,65 +71,6 @@ _sbrk_r(struct _reent *ptr, ptrdiff_t incr) return __wut_sbrk_r(ptr, incr); } -void -__syscall_lock_init(int *lock) -{ - __wut_lock_init(lock, 0); -} - -void -__syscall_lock_acquire(int *lock) -{ - __wut_lock_acquire(lock); -} - -void -__syscall_lock_release(int *lock) -{ - __wut_lock_release(lock); -} - -void -__syscall_lock_close(int *lock) -{ - __wut_lock_close(lock); -} -void -__syscall_lock_init_recursive(_LOCK_T *lock) -{ - __wut_lock_init(lock, 1); -} - -void -__syscall_lock_acquire_recursive(int *lock) -{ - __wut_lock_acquire(lock); -} - -void -__syscall_lock_release_recursive(int *lock) -{ - __wut_lock_release(lock); -} - -void -__syscall_lock_close_recursive(int *lock) -{ - __wut_lock_close(lock); -} - -void -__syscall_malloc_lock(struct _reent *ptr) -{ - return __wut_malloc_lock(ptr); -} - -void -__syscall_malloc_unlock(struct _reent *ptr) -{ - return __wut_malloc_unlock(ptr); -} - struct _reent * __syscall_getreent(void) { diff --git a/libraries/wutnewlib/wut_newlib.h b/libraries/wutnewlib/wut_newlib.h index 5f9301d4f..f3b13ae13 100644 --- a/libraries/wutnewlib/wut_newlib.h +++ b/libraries/wutnewlib/wut_newlib.h @@ -6,21 +6,14 @@ #include #include +#define __WUT_MAX_KEYS (128) +#define __WUT_STACK_SIZE (128 * 1024) + +#define __WUT_KEY_THREAD_SPECIFIC_ID WUT_THREAD_SPECIFIC_0 + void * __wut_sbrk_r(struct _reent *r, ptrdiff_t incr); int -__wut_lock_init(int *lock, int recursive); -int -__wut_lock_close(int *lock); -int -__wut_lock_acquire(int *lock); -int -__wut_lock_release(int *lock); -void -__wut_malloc_lock(struct _reent *r); -void -__wut_malloc_unlock(struct _reent *r); -int __wut_gettod_r(struct _reent *ptr, struct timeval *tp, struct timezone *tz); int __wut_clock_gettime(clockid_t clock_id, struct timespec *tp); diff --git a/libraries/wutnewlib/wut_thread.c b/libraries/wutnewlib/wut_thread.c new file mode 100644 index 000000000..2b66f5ebf --- /dev/null +++ b/libraries/wutnewlib/wut_thread.c @@ -0,0 +1,287 @@ +#include "wut_newlib.h" + +#include + +#include +#include +#include +#include +#include +#include +#include + +static OSSpinLock sSyncSpinLock; +static OSSpinLock sMallocSpinLock; + +void +__init_wut_thread() +{ + OSInitSpinLock(&sSyncSpinLock); + OSInitSpinLock(&sMallocSpinLock); +} + +static OSFastMutex* +__wut_get_mutex(_LOCK_T *lock) +{ + if (*lock) { + return (OSFastMutex*)*lock; + } + + OSUninterruptibleSpinLock_Acquire(&sSyncSpinLock); + + OSFastMutex* m = (OSFastMutex*)*lock; + if (!m) { + m = MEMAllocFromDefaultHeap(sizeof(OSFastMutex)); + OSFastMutex_Init(m, NULL); + *lock = (uint32_t)m; + } + + OSUninterruptibleSpinLock_Release(&sSyncSpinLock); + + return m; +} + +static OSFastCondition* +__wut_get_cond(_COND_T *cond) +{ + if (*cond) { + return (OSFastCondition*)*cond; + } + + OSUninterruptibleSpinLock_Acquire(&sSyncSpinLock); + + OSFastCondition* c = (OSFastCondition*)*cond; + if (!c) { + c = MEMAllocFromDefaultHeap(sizeof(OSFastCondition)); + OSFastCond_Init(c, NULL); + *cond = (uint32_t)c; + } + + OSUninterruptibleSpinLock_Release(&sSyncSpinLock); + + return c; +} + +void +__SYSCALL(malloc_lock)(struct _reent *ptr) +{ + OSUninterruptibleSpinLock_Acquire(&sMallocSpinLock); +} + +void +__SYSCALL(malloc_unlock)(struct _reent *ptr) +{ + OSUninterruptibleSpinLock_Release(&sMallocSpinLock); +} + +void +__SYSCALL(lock_close)(_LOCK_T *lock) +{ + if (*lock) { + MEMFreeToDefaultHeap((void*)*lock); + *lock = 0; + } +} + +void +__SYSCALL(lock_acquire)(_LOCK_T *lock) +{ + OSFastMutex_Lock(__wut_get_mutex(lock)); +} + +int +__SYSCALL(lock_try_acquire)(_LOCK_T *lock) +{ + return OSFastMutex_TryLock(__wut_get_mutex(lock)); +} + +void +__SYSCALL(lock_release)(_LOCK_T *lock) +{ + OSFastMutex_Unlock(__wut_get_mutex(lock)); +} + +void +__SYSCALL(lock_close_recursive)(_LOCK_RECURSIVE_T *lock) +{ + __SYSCALL(lock_close)(&lock->lock); +} + +void +__SYSCALL(lock_acquire_recursive)(_LOCK_RECURSIVE_T *lock) +{ + __SYSCALL(lock_acquire)(&lock->lock); +} + +int32_t +__SYSCALL(lock_try_acquire_recursive)(_LOCK_RECURSIVE_T *lock) +{ + return __SYSCALL(lock_try_acquire)(&lock->lock); +} + +void +__SYSCALL(lock_release_recursive)(_LOCK_RECURSIVE_T *lock) +{ + __SYSCALL(lock_release)(&lock->lock); +} + +void +__SYSCALL(cond_close)(_COND_T *cond) +{ + if (*cond) { + MEMFreeToDefaultHeap((void*)*cond); + *cond = 0; + } +} + +int +__SYSCALL(cond_signal)(_COND_T *cond) +{ + OSFastCond_Signal(__wut_get_cond(cond)); // XX: this is broadcast + return 0; +} + +int +__SYSCALL(cond_broadcast)(_COND_T *cond) +{ + OSFastCond_Signal(__wut_get_cond(cond)); + return 0; +} + +typedef struct { + OSFastCondition *cond; + bool timed_out; +} __wut_condwait_t; + +static void +__wut_cond_alarmcb(OSAlarm *alarm, OSContext *context) +{ + __wut_condwait_t *data = OSGetAlarmUserData(alarm); + data->timed_out = true; + OSFastCond_Signal(data->cond); +} + +int +__SYSCALL(cond_wait)(_COND_T *cond, _LOCK_T *lock, uint64_t timeout_ns) +{ + if (timeout_ns == UINT64_MAX) { + OSFastCond_Wait(__wut_get_cond(cond), __wut_get_mutex(lock)); + return 0; + } + + __wut_condwait_t data; + data.cond = __wut_get_cond(cond); + data.timed_out = false; + + OSAlarm alarm; + OSCreateAlarm(&alarm); + OSSetAlarmUserData(&alarm, &data); + OSSetAlarm(&alarm, OSNanosecondsToTicks(timeout_ns), __wut_cond_alarmcb); + OSFastCond_Wait(data.cond, __wut_get_mutex(lock)); + OSCancelAlarm(&alarm); + + return data.timed_out ? ETIMEDOUT : 0; +} + +int +__SYSCALL(cond_wait_recursive)(_COND_T *cond, _LOCK_RECURSIVE_T *lock, uint64_t timeout_ns) +{ + return __SYSCALL(cond_wait)(cond, &lock->lock, timeout_ns); +} + +struct __pthread_t { + OSThread base; +}; + +int +__SYSCALL(thread_create)(struct __pthread_t **thread, void* (*func)(void*), void *arg, void *stack_addr, size_t stack_size) +{ + if (!stack_size) { + stack_size = __WUT_STACK_SIZE; + } + + uint32_t alloc_size = sizeof(struct __pthread_t); + alloc_size = (alloc_size + 15) &~ 15; + stack_size = stack_size &~ 15; + + if (!stack_addr) { + alloc_size += stack_size; + } + + struct __pthread_t *t = MEMAllocFromDefaultHeapEx(alloc_size, 0x10); + if (!t) { + return ENOMEM; + } + + memset(t, 0, sizeof(*t)); + + if (!stack_addr) { + stack_addr = (char*)t + alloc_size; + } else { + stack_addr = (char*)stack_addr + stack_size; + } + + BOOL ok = OSCreateThread( + &t->base, + (OSThreadEntryPointFn)func, + (int32_t)arg, + NULL, + stack_addr, + stack_size, + 16, + OS_THREAD_ATTRIB_AFFINITY_ANY + ); + + if (!ok) { + MEMFreeToDefaultHeap(t); + return EINVAL; + } + + *thread = t; + OSSetThreadDeallocator(&t->base, (OSThreadDeallocatorFn)MEMFreeToDefaultHeap); + //XX: OSSetThreadCleanupCallback: use to free TLS slots + + // Enable timeslicing, using 1ms as the thread run quantum + OSSetThreadRunQuantum(&t->base, 1000); + + OSResumeThread(&t->base); + return 0; +} + +void* +__SYSCALL(thread_join)(struct __pthread_t *thread) +{ + int res = 0; + OSJoinThread(&thread->base, &res); // XX: assert? + return (void*)res; +} + +int +__SYSCALL(thread_detach)(struct __pthread_t *thread) +{ + OSDetachThread(&thread->base); + return 0; +} + +void +__SYSCALL(thread_exit)(void *value) +{ + OSExitThread((int)value); +} + +struct __pthread_t * +__SYSCALL(thread_self)(void) +{ + return (struct __pthread_t*)OSGetCurrentThread(); +} + +int sched_yield(void) +{ + OSYieldThread(); + return 0; +} + +int sched_getcpu(void) +{ + return OSGetCoreId(); +} diff --git a/libraries/wutstdc++/wut_gthread.cpp b/libraries/wutstdc++/wut_gthread.cpp deleted file mode 100644 index c15a9469d..000000000 --- a/libraries/wutstdc++/wut_gthread.cpp +++ /dev/null @@ -1,197 +0,0 @@ -#include "wut_gthread.h" -#include -#include - -static constexpr __wut_key_t -gthread_key_to_wut(__gthread_key_t key) -{ - __wut_key_t dst = {}; - static_assert(sizeof(__wut_key_t) == sizeof(__gthread_key_t), "Incompatible definition of thread local key type"); - __builtin_memcpy(&dst, &key, sizeof(dst)); - return dst; -} - -extern "C" { - -int -__gthr_impl_active(void) -{ - return 1; -} - -int -__gthr_impl_create(__gthread_t *__threadid, void *(*__func)(void *), void *__args) -{ - return __wut_thread_create((OSThread **)__threadid, __func, __args); -} - -int -__gthr_impl_join(__gthread_t __threadid, void **__value_ptr) -{ - return __wut_thread_join((OSThread *)__threadid, __value_ptr); -} - -int -__gthr_impl_detach(__gthread_t __threadid) -{ - return __wut_thread_detach((OSThread *)__threadid); -} - -int -__gthr_impl_equal(__gthread_t __t1, __gthread_t __t2) -{ - return __wut_thread_equal((OSThread *)__t1, (OSThread *)__t2); -} - -__gthread_t -__gthr_impl_self(void) -{ - return __wut_thread_self(); -} - -int -__gthr_impl_yield(void) -{ - return __wut_thread_yield(); -} - -int -__gthr_impl_once(__gthread_once_t *__once, void (*__func)(void)) -{ - return __wut_once((__wut_once_t *)__once, __func); -} - -int -__gth_impl_key_create(__gthread_key_t *__key, void (*__dtor)(void *)) -{ - return __wut_key_create((__wut_key_t *)__key, __dtor); -} - -int -__gthr_impl_key_delete(__gthread_key_t __key) -{ - return __wut_key_delete(gthread_key_to_wut(__key)); -} -void * -__gthr_impl_getspecific(__gthread_key_t __key) -{ - return __wut_getspecific(gthread_key_to_wut(__key)); -} -int -__gthr_impl_setspecific(__gthread_key_t __key, const void *__ptr) -{ - return __wut_setspecific(gthread_key_to_wut(__key), __ptr); -} - -void -__gthr_impl_mutex_init_function(__gthread_mutex_t *__mutex) -{ - return __wut_mutex_init_function((OSMutex *)__mutex); -} - -int -__gthr_impl_mutex_destroy(__gthread_mutex_t *__mutex) -{ - return __wut_mutex_destroy((OSMutex *)__mutex); -} -int -__gthr_impl_mutex_lock(__gthread_mutex_t *__mutex) -{ - return __wut_mutex_lock((OSMutex *)__mutex); -} - -int -__gthr_impl_mutex_trylock(__gthread_mutex_t *__mutex) -{ - return __wut_mutex_trylock((OSMutex *)__mutex); -} - -int -__gthr_impl_mutex_unlock(__gthread_mutex_t *__mutex) -{ - return __wut_mutex_unlock((OSMutex *)__mutex); -} - -int -__gthr_impl_recursive_mutex_init_function(__gthread_recursive_mutex_t *__mutex) -{ - return __wut_recursive_mutex_init_function((OSMutex *)__mutex); -} - -int -__gthr_impl_recursive_mutex_lock(__gthread_recursive_mutex_t *__mutex) -{ - return __wut_recursive_mutex_lock((OSMutex *)__mutex); -} - -int -__gthr_impl_recursive_mutex_trylock(__gthread_recursive_mutex_t *__mutex) -{ - return __wut_recursive_mutex_trylock((OSMutex *)__mutex); -} - -int -__gthr_impl_recursive_mutex_unlock(__gthread_recursive_mutex_t *__mutex) -{ - return __wut_recursive_mutex_unlock((OSMutex *)__mutex); -} - -int -__gthr_impl_recursive_mutex_destroy(__gthread_recursive_mutex_t *__mutex) -{ - return __wut_recursive_mutex_destroy((OSMutex *)__mutex); -} - -void -__gthr_impl_cond_init_function(__gthread_cond_t *__cond) -{ - return __wut_cond_init_function((OSCondition *)__cond); -} - -int -__gthr_impl_cond_broadcast(__gthread_cond_t *__cond) -{ - return __wut_cond_broadcast((OSCondition *)__cond); -} - -int -__gthr_impl_cond_signal(__gthread_cond_t *__cond) -{ - return __wut_cond_signal((OSCondition *)__cond); -} - -int -__gthr_impl_cond_wait(__gthread_cond_t *__cond, __gthread_mutex_t *__mutex) -{ - return __wut_cond_wait((OSCondition *)__cond, (OSMutex *)__mutex); -} - -int -__gthr_impl_cond_timedwait(__gthread_cond_t *__cond, __gthread_mutex_t *__mutex, const __gthread_time_t *__abs_timeout) -{ - return __wut_cond_timedwait((OSCondition *)__cond, (OSMutex *)__mutex, __abs_timeout); -} - -int -__gthr_impl_cond_wait_recursive(__gthread_cond_t *__cond, __gthread_recursive_mutex_t *__mutex) -{ - return __wut_cond_wait_recursive((OSCondition *)__cond, (OSMutex *)__mutex); -} - -int -__gthr_impl_cond_destroy(__gthread_cond_t *__cond) -{ - return __wut_cond_destroy((OSCondition *)__cond); -} - - -void -__init_wut_stdcpp() -{ -} - -void -__fini_wut_stdcpp() -{ -} -} diff --git a/libraries/wutstdc++/wut_gthread.h b/libraries/wutstdc++/wut_gthread.h deleted file mode 100644 index 7788bb4e5..000000000 --- a/libraries/wutstdc++/wut_gthread.h +++ /dev/null @@ -1,128 +0,0 @@ -#pragma once -#include - -#include -#include -#include -#include - -#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 WUT_THREAD_SPECIFIC_0 - -typedef volatile uint32_t __wut_once_t; -typedef struct -{ - uint32_t index; -} __wut_key_t; - -void -__init_wut_gthread(); - -int -__wut_active_p(); - -int -__wut_thread_create(OSThread **outThread, - void *(*func)(void *), - void *args); - -int -__wut_thread_join(OSThread *thread, - void **outValue); - -int -__wut_thread_detach(OSThread *thread); - -int -__wut_thread_equal(OSThread *thread1, - OSThread *thread2); - -OSThread * -__wut_thread_self(); - -int -__wut_thread_yield(); - -int -__wut_once(__wut_once_t *once, - void (*func)(void)); - -void -__wut_key_cleanup(OSThread *thread); - -int -__wut_key_create(__wut_key_t *key, - void (*dtor)(void *)); - -int -__wut_key_delete(__wut_key_t key); - -void * -__wut_getspecific(__wut_key_t key); - -int -__wut_setspecific(__wut_key_t key, - const void *ptr); - -void -__wut_mutex_init_function(OSMutex *mutex); - -int -__wut_mutex_destroy(OSMutex *mutex); - -int -__wut_mutex_lock(OSMutex *mutex); - -int -__wut_mutex_trylock(OSMutex *mutex); - -int -__wut_mutex_unlock(OSMutex *mutex); - -int -__wut_recursive_mutex_init_function(OSMutex *mutex); - -int -__wut_recursive_mutex_lock(OSMutex *mutex); - -int -__wut_recursive_mutex_trylock(OSMutex *mutex); - -int -__wut_recursive_mutex_unlock(OSMutex *mutex); - -int -__wut_recursive_mutex_destroy(OSMutex *mutex); - -void -__wut_cond_init_function(OSCondition *cond); - -int -__wut_cond_broadcast(OSCondition *cond); - -int -__wut_cond_signal(OSCondition *cond); - -int -__wut_cond_wait(OSCondition *cond, - OSMutex *mutex); - -int -__wut_cond_timedwait(OSCondition *cond, - OSMutex *mutex, - const __gthread_time_t *abs_timeout); - -int -__wut_cond_wait_recursive(OSCondition *cond, - OSMutex *mutex); - -int -__wut_cond_destroy(OSCondition *cond); diff --git a/libraries/wutstdc++/wut_gthread_cond.cpp b/libraries/wutstdc++/wut_gthread_cond.cpp deleted file mode 100644 index fe1f3a503..000000000 --- a/libraries/wutstdc++/wut_gthread_cond.cpp +++ /dev/null @@ -1,97 +0,0 @@ -#include "wut_gthread.h" -#include "../wutnewlib/wut_clock.h" - -#include -#include - -#include -#include -#include - -void -__wut_cond_init_function(OSCondition *cond) -{ - OSInitCond(cond); -} - -int -__wut_cond_broadcast(OSCondition *cond) -{ - OSSignalCond(cond); - return 0; -} - -int -__wut_cond_signal(OSCondition *cond) -{ - OSSignalCond(cond); - return 0; -} - -int -__wut_cond_wait(OSCondition *cond, - OSMutex *mutex) -{ - OSWaitCond(cond, mutex); - return 0; -} - -struct __wut_cond_timedwait_data_t -{ - OSCondition *cond; - bool timed_out; -}; - -static void -__wut_cond_timedwait_alarm_callback(OSAlarm *alarm, - OSContext *context) -{ - __wut_cond_timedwait_data_t *data = (__wut_cond_timedwait_data_t *)OSGetAlarmUserData(alarm); - data->timed_out = true; - OSSignalCond(data->cond); -} - -int -__wut_cond_timedwait(OSCondition *cond, OSMutex *mutex, const __gthread_time_t *abs_timeout) -{ - __wut_cond_timedwait_data_t data; - data.timed_out = false; - data.cond = cond; - - OSTime time = OSGetTime(); - OSTime timeout = - OSSecondsToTicks(abs_timeout->tv_sec - EPOCH_DIFF_SECS(WIIU_OSTIME_EPOCH_YEAR)) + - OSNanosecondsToTicks(abs_timeout->tv_nsec); - - // Already timed out! - if (timeout <= time) { - return ETIMEDOUT; - } - - // Set an alarm - OSAlarm alarm; - OSCreateAlarm(&alarm); - OSSetAlarmUserData(&alarm, &data); - OSSetAlarm(&alarm, timeout - time, - &__wut_cond_timedwait_alarm_callback); - - // Wait on the condition - OSWaitCond(cond, mutex); - - OSCancelAlarm(&alarm); - return data.timed_out ? ETIMEDOUT : 0; -} - -int -__wut_cond_wait_recursive(OSCondition *cond, - OSMutex *mutex) -{ - OSWaitCond(cond, mutex); - return 0; -} - -int -__wut_cond_destroy(OSCondition *cond) -{ - return 0; -} diff --git a/libraries/wutstdc++/wut_gthread_keys.cpp b/libraries/wutstdc++/wut_gthread_keys.cpp deleted file mode 100644 index ec54292ae..000000000 --- a/libraries/wutstdc++/wut_gthread_keys.cpp +++ /dev/null @@ -1,119 +0,0 @@ -#include "wut_gthread.h" - -#include -#include -#include - -struct __wut_key_table_entry -{ - bool in_use; - void (*dtor)(void *); -}; - -static __wut_key_table_entry key_table[__WUT_MAX_KEYS]; - -static OSMutex key_mutex; -static __wut_once_t init_once_control = __WUT_ONCE_VALUE_INIT; - -static void -init() -{ - __wut_mutex_init_function(&key_mutex); - memset(key_table, 0, sizeof(key_table)); -} - -int -__wut_key_create(__wut_key_t *key, - void (*dtor)(void *)) -{ - int res = EAGAIN; - __wut_once(&init_once_control, init); - __wut_mutex_lock(&key_mutex); - - for (uint32_t i = 0; i < __WUT_MAX_KEYS; ++i) { - if (key_table[i].in_use) { - continue; - } - - key_table[i].in_use = 1; - key_table[i].dtor = dtor; - - res = 0; - key->index = i; - break; - } - - __wut_mutex_unlock(&key_mutex); - return res; -} - -int -__wut_key_delete(__wut_key_t key) -{ - __wut_mutex_lock(&key_mutex); - key_table[key.index].in_use = 0; - key_table[key.index].dtor = NULL; - __wut_mutex_unlock(&key_mutex); - return -1; -} - -static const void ** -__wut_get_thread_keys() -{ - 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)); - wut_set_thread_specific(__WUT_KEY_THREAD_SPECIFIC_ID, keys); - } - - return keys; -} - -void * -__wut_getspecific(__wut_key_t key) -{ - const void **keys = __wut_get_thread_keys(); - if (!keys) { - return NULL; - } - - return (void *)(keys[key.index]); -} - -int -__wut_setspecific(__wut_key_t key, - const void *ptr) -{ - const void **keys = __wut_get_thread_keys(); - if (!keys) { - return -1; - } - - keys[key.index] = ptr; - return 0; -} - -void -__wut_key_cleanup(OSThread *thread) -{ - void **keys = (void **)wut_get_thread_specific(__WUT_KEY_THREAD_SPECIFIC_ID); - if (!keys) { - return; - } - - __wut_mutex_lock(&key_mutex); - - for (int i = 0; i < __WUT_MAX_KEYS; ++i) { - if (key_table[i].in_use && key_table[i].dtor && keys[i]) { - key_table[i].dtor(keys[i]); - } - } - - __wut_mutex_unlock(&key_mutex); - free(keys); -} diff --git a/libraries/wutstdc++/wut_gthread_mutex.cpp b/libraries/wutstdc++/wut_gthread_mutex.cpp deleted file mode 100644 index 1dae3f890..000000000 --- a/libraries/wutstdc++/wut_gthread_mutex.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "wut_gthread.h" - -void -__wut_mutex_init_function(OSMutex *mutex) -{ - OSInitMutex(mutex); -} - -int -__wut_mutex_lock(OSMutex *mutex) -{ - OSLockMutex(mutex); - return 0; -} - -int -__wut_mutex_trylock(OSMutex *mutex) -{ - if (!OSTryLockMutex(mutex)) { - return -1; - } - - return 0; -} - -int -__wut_mutex_unlock(OSMutex *mutex) -{ - OSUnlockMutex(mutex); - return 0; -} - -int -__wut_mutex_destroy(OSMutex *mutex) -{ - return 0; -} diff --git a/libraries/wutstdc++/wut_gthread_once.cpp b/libraries/wutstdc++/wut_gthread_once.cpp deleted file mode 100644 index 5fb4a1d72..000000000 --- a/libraries/wutstdc++/wut_gthread_once.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include "wut_gthread.h" - -int -__wut_once(__wut_once_t *once, - void (*func)(void)) -{ - uint32_t value = 0; - - if (OSCompareAndSwapAtomicEx(once, - __WUT_ONCE_VALUE_INIT, - __WUT_ONCE_VALUE_STARTED, - &value)) { - func(); - OSSwapAtomic(once, - __WUT_ONCE_VALUE_DONE); - } else if (value != __WUT_ONCE_VALUE_DONE) { - while (!OSCompareAndSwapAtomic(once, - __WUT_ONCE_VALUE_DONE, - __WUT_ONCE_VALUE_DONE)); - } - - return 0; -} diff --git a/libraries/wutstdc++/wut_gthread_recursive_mutex.cpp b/libraries/wutstdc++/wut_gthread_recursive_mutex.cpp deleted file mode 100644 index 7664b479b..000000000 --- a/libraries/wutstdc++/wut_gthread_recursive_mutex.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "wut_gthread.h" - -int -__wut_recursive_mutex_init_function(OSMutex *mutex) -{ - OSInitMutex(mutex); - return 0; -} - -int -__wut_recursive_mutex_lock(OSMutex *mutex) -{ - OSLockMutex(mutex); - return 0; -} - -int -__wut_recursive_mutex_trylock(OSMutex *mutex) -{ - if (!OSTryLockMutex(mutex)) { - return -1; - } - - return 0; -} - -int -__wut_recursive_mutex_unlock(OSMutex *mutex) -{ - OSUnlockMutex(mutex); - return 0; -} - -int -__wut_recursive_mutex_destroy(OSMutex *mutex) -{ - return 0; -} diff --git a/libraries/wutstdc++/wut_gthread_thread.cpp b/libraries/wutstdc++/wut_gthread_thread.cpp deleted file mode 100644 index 3bffff2ea..000000000 --- a/libraries/wutstdc++/wut_gthread_thread.cpp +++ /dev/null @@ -1,102 +0,0 @@ -#include "wut_gthread.h" - -#include -#include -#include -#include -uint32_t __attribute__((weak)) __wut_thread_default_stack_size = __WUT_STACK_SIZE; - -static void -__wut_thread_deallocator(OSThread *thread, - void *stack) -{ - free(thread); - free(stack); -} - -static void -__wut_thread_cleanup(OSThread *thread, void *stack) -{ - __wut_key_cleanup(thread); -} - -int -__wut_thread_create(OSThread **outThread, - void *(*entryPoint)(void *), - void *entryArgs) -{ - OSThread *thread = (OSThread *)memalign(16, sizeof(OSThread)); - if (!thread) { - return ENOMEM; - } - - memset(thread, 0, sizeof(OSThread)); - - char *stack = (char *)memalign(16, __wut_thread_default_stack_size); - if (!stack) { - free(thread); - return ENOMEM; - } - - if (!OSCreateThread(thread, - (OSThreadEntryPointFn)entryPoint, - (int)entryArgs, - NULL, - stack + __wut_thread_default_stack_size, - __wut_thread_default_stack_size, - 16, - OS_THREAD_ATTRIB_AFFINITY_ANY)) { - free(thread); - free(stack); - return EINVAL; - } - - *outThread = thread; - OSSetThreadDeallocator(thread, &__wut_thread_deallocator); - OSSetThreadCleanupCallback(thread, &__wut_thread_cleanup); - - // Set a thread run quantum to 1 millisecond, to force the threads to - // behave more like pre-emptive scheduling rather than co-operative. - OSSetThreadRunQuantum(thread, 1000); - - OSResumeThread(thread); - return 0; -} - -int -__wut_thread_join(OSThread *thread, - void **outValue) -{ - if (!OSJoinThread(thread, (int *)outValue)) { - return EINVAL; - } - - return 0; -} - -int -__wut_thread_detach(OSThread *thread) -{ - OSDetachThread(thread); - return 0; -} - -int -__wut_thread_equal(OSThread *thread1, - OSThread *thread2) -{ - return thread1 == thread2; -} - -OSThread * -__wut_thread_self() -{ - return OSGetCurrentThread(); -} - -int -__wut_thread_yield() -{ - OSYieldThread(); - return 0; -} From 29f197a5578f281f6011effed054c7d42bba2af3 Mon Sep 17 00:00:00 2001 From: fincs Date: Sun, 25 Jan 2026 19:31:37 +0100 Subject: [PATCH 2/2] Pain --- libraries/wutnewlib/wut_thread.c | 66 +++++++++++++++++--------------- 1 file changed, 36 insertions(+), 30 deletions(-) diff --git a/libraries/wutnewlib/wut_thread.c b/libraries/wutnewlib/wut_thread.c index 2b66f5ebf..53b5c3280 100644 --- a/libraries/wutnewlib/wut_thread.c +++ b/libraries/wutnewlib/wut_thread.c @@ -2,13 +2,13 @@ #include -#include #include -#include -#include -#include #include +#include +#include #include +#include +#include static OSSpinLock sSyncSpinLock; static OSSpinLock sMallocSpinLock; @@ -20,16 +20,16 @@ __init_wut_thread() OSInitSpinLock(&sMallocSpinLock); } -static OSFastMutex* +static OSFastMutex * __wut_get_mutex(_LOCK_T *lock) { if (*lock) { - return (OSFastMutex*)*lock; + return (OSFastMutex *)*lock; } OSUninterruptibleSpinLock_Acquire(&sSyncSpinLock); - OSFastMutex* m = (OSFastMutex*)*lock; + OSFastMutex *m = (OSFastMutex *)*lock; if (!m) { m = MEMAllocFromDefaultHeap(sizeof(OSFastMutex)); OSFastMutex_Init(m, NULL); @@ -41,16 +41,16 @@ __wut_get_mutex(_LOCK_T *lock) return m; } -static OSFastCondition* +static OSFastCondition * __wut_get_cond(_COND_T *cond) { if (*cond) { - return (OSFastCondition*)*cond; + return (OSFastCondition *)*cond; } OSUninterruptibleSpinLock_Acquire(&sSyncSpinLock); - OSFastCondition* c = (OSFastCondition*)*cond; + OSFastCondition *c = (OSFastCondition *)*cond; if (!c) { c = MEMAllocFromDefaultHeap(sizeof(OSFastCondition)); OSFastCond_Init(c, NULL); @@ -78,7 +78,7 @@ void __SYSCALL(lock_close)(_LOCK_T *lock) { if (*lock) { - MEMFreeToDefaultHeap((void*)*lock); + MEMFreeToDefaultHeap((void *)*lock); *lock = 0; } } @@ -104,13 +104,15 @@ __SYSCALL(lock_release)(_LOCK_T *lock) void __SYSCALL(lock_close_recursive)(_LOCK_RECURSIVE_T *lock) { - __SYSCALL(lock_close)(&lock->lock); + __SYSCALL(lock_close) + (&lock->lock); } void __SYSCALL(lock_acquire_recursive)(_LOCK_RECURSIVE_T *lock) { - __SYSCALL(lock_acquire)(&lock->lock); + __SYSCALL(lock_acquire) + (&lock->lock); } int32_t @@ -122,14 +124,15 @@ __SYSCALL(lock_try_acquire_recursive)(_LOCK_RECURSIVE_T *lock) void __SYSCALL(lock_release_recursive)(_LOCK_RECURSIVE_T *lock) { - __SYSCALL(lock_release)(&lock->lock); + __SYSCALL(lock_release) + (&lock->lock); } void __SYSCALL(cond_close)(_COND_T *cond) { if (*cond) { - MEMFreeToDefaultHeap((void*)*cond); + MEMFreeToDefaultHeap((void *)*cond); *cond = 0; } } @@ -148,7 +151,8 @@ __SYSCALL(cond_broadcast)(_COND_T *cond) return 0; } -typedef struct { +typedef struct +{ OSFastCondition *cond; bool timed_out; } __wut_condwait_t; @@ -189,20 +193,21 @@ __SYSCALL(cond_wait_recursive)(_COND_T *cond, _LOCK_RECURSIVE_T *lock, uint64_t return __SYSCALL(cond_wait)(cond, &lock->lock, timeout_ns); } -struct __pthread_t { - OSThread base; +struct __pthread_t +{ + OSThread base; }; int -__SYSCALL(thread_create)(struct __pthread_t **thread, void* (*func)(void*), void *arg, void *stack_addr, size_t stack_size) +__SYSCALL(thread_create)(struct __pthread_t **thread, void *(*func)(void *), void *arg, void *stack_addr, size_t stack_size) { if (!stack_size) { stack_size = __WUT_STACK_SIZE; } uint32_t alloc_size = sizeof(struct __pthread_t); - alloc_size = (alloc_size + 15) &~ 15; - stack_size = stack_size &~ 15; + alloc_size = (alloc_size + 15) & ~15; + stack_size = stack_size & ~15; if (!stack_addr) { alloc_size += stack_size; @@ -216,9 +221,9 @@ __SYSCALL(thread_create)(struct __pthread_t **thread, void* (*func)(void*), void memset(t, 0, sizeof(*t)); if (!stack_addr) { - stack_addr = (char*)t + alloc_size; + stack_addr = (char *)t + alloc_size; } else { - stack_addr = (char*)stack_addr + stack_size; + stack_addr = (char *)stack_addr + stack_size; } BOOL ok = OSCreateThread( @@ -229,8 +234,7 @@ __SYSCALL(thread_create)(struct __pthread_t **thread, void* (*func)(void*), void stack_addr, stack_size, 16, - OS_THREAD_ATTRIB_AFFINITY_ANY - ); + OS_THREAD_ATTRIB_AFFINITY_ANY); if (!ok) { MEMFreeToDefaultHeap(t); @@ -248,12 +252,12 @@ __SYSCALL(thread_create)(struct __pthread_t **thread, void* (*func)(void*), void return 0; } -void* +void * __SYSCALL(thread_join)(struct __pthread_t *thread) { int res = 0; OSJoinThread(&thread->base, &res); // XX: assert? - return (void*)res; + return (void *)res; } int @@ -272,16 +276,18 @@ __SYSCALL(thread_exit)(void *value) struct __pthread_t * __SYSCALL(thread_self)(void) { - return (struct __pthread_t*)OSGetCurrentThread(); + return (struct __pthread_t *)OSGetCurrentThread(); } -int sched_yield(void) +int +sched_yield(void) { OSYieldThread(); return 0; } -int sched_getcpu(void) +int +sched_getcpu(void) { return OSGetCoreId(); }