From 98da847bf510ceb380a00e432bccbbc826725ce2 Mon Sep 17 00:00:00 2001 From: PJB3005 Date: Sun, 29 Mar 2026 01:54:45 +0100 Subject: [PATCH] OSThread fixes OSCancelThread and OSDetachThread stubbed out cuz they're probably both broken Code cleanup, unnecessary code copied from decomp removed, copy-paste reduced. Don't immediately detach threads when creating them (what's the point??) Fix OSJoinThread --- src/dusk/OSThread.cpp | 88 ++++++++++++------------------------------- 1 file changed, 24 insertions(+), 64 deletions(-) diff --git a/src/dusk/OSThread.cpp b/src/dusk/OSThread.cpp index 7daa2cb137..322d33a331 100644 --- a/src/dusk/OSThread.cpp +++ b/src/dusk/OSThread.cpp @@ -17,6 +17,7 @@ #include #include "JSystem/JKernel/JKRHeap.h" +#include "dusk/main.h" #include "dusk/os.h" #if _WIN32 @@ -36,6 +37,13 @@ struct PCThreadData { void* param; bool started = false; bool suspended = false; + + ~PCThreadData() { + if (dusk::IsShuttingDown) { + // Don't care about threads if we're shutting down. + nativeThread.detach(); + } + } }; // Lazy-initialized to avoid DLL static init crashes (used before DllMain completes) @@ -48,6 +56,16 @@ static std::unordered_map>& GetThreadDa return map; } +static PCThreadData* GetThreadData(OSThread* thread) { + std::lock_guard mapLock(GetThreadDataMutex()); + auto it = GetThreadDataMap().find(thread); + if (it != GetThreadDataMap().end()) { + return it->second.get(); + } + + return nullptr; +} + // Side-table for OSThreadQueue -> condition_variable (for OSSleepThread/OSWakeupThread) static std::mutex& GetQueueCvMutex() { static std::mutex mtx; @@ -83,8 +101,6 @@ static OSThread sDefaultThread; static u8 sDefaultStack[64 * 1024]; static u32 sDefaultStackEnd = OS_THREAD_STACK_MAGIC; -OSThreadQueue __OSActiveThreadQueue; - // Global interrupt mutex (coarse-grained lock replacing interrupt disable) // Lazy-initialized to avoid DLL static init crashes static std::recursive_mutex& GetInterruptMutex() { @@ -106,36 +122,6 @@ static OSSwitchThreadCallback sSwitchThreadCallback = nullptr; // Internal helpers // ============================================================================ -// Linked list macros for the active thread queue -static void EnqueueActive(OSThread* thread) { - OSThread* prev = __OSActiveThreadQueue.tail; - if (prev == nullptr) { - __OSActiveThreadQueue.head = thread; - } else { - prev->linkActive.next = thread; - } - thread->linkActive.prev = prev; - thread->linkActive.next = nullptr; - __OSActiveThreadQueue.tail = thread; -} - -static void DequeueActive(OSThread* thread) { - OSThread* next = thread->linkActive.next; - OSThread* prev = thread->linkActive.prev; - if (next == nullptr) { - __OSActiveThreadQueue.tail = prev; - } else { - next->linkActive.prev = prev; - } - if (prev == nullptr) { - __OSActiveThreadQueue.head = next; - } else { - prev->linkActive.next = next; - } - thread->linkActive.next = nullptr; - thread->linkActive.prev = nullptr; -} - // Thread entry wrapper - runs on the new std::thread static void ThreadEntryWrapper(OSThread* thread, PCThreadData* data) { // Set thread-local pointer @@ -193,8 +179,6 @@ void __OSThreadInit(void) { tls_currentThread = &sDefaultThread; // Active queue - OSInitThreadQueue(&__OSActiveThreadQueue); - EnqueueActive(&sDefaultThread); sActiveThreadCount = 1; OSReport("[PC-OSThread] Thread system initialized (multi-threaded mode)\n"); @@ -271,7 +255,6 @@ int OSCreateThread(OSThread* thread, void* (*func)(void*), void* param, } // Add to active queue - EnqueueActive(thread); sActiveThreadCount++; OSReport("[PC-OSThread] Created thread %p (priority=%d, stackSize=%u)\n", @@ -351,16 +334,7 @@ s32 OSResumeThread(OSThread* thread) { // Only wake up if suspend count drops to 0 if (thread->suspend == 0) { - PCThreadData* data = nullptr; - - // Lock the global map to safely retrieve our thread data pointer - { - std::lock_guard mapLock(GetThreadDataMutex()); - auto it = GetThreadDataMap().find(thread); - if (it != GetThreadDataMap().end()) { - data = it->second.get(); - } - } + PCThreadData* data = GetThreadData(thread); if (data) { // Lock the specific thread mutex to safely modify state and notify @@ -375,7 +349,6 @@ s32 OSResumeThread(OSThread* thread) { threadLock.unlock(); data->nativeThread = std::thread(ThreadEntryWrapper, thread, data); - data->nativeThread.detach(); OSReport("[PC-OSThread] Started thread %p\n", thread); } else { // Resume from suspension: signal the condition variable @@ -398,16 +371,7 @@ s32 OSSuspendThread(OSThread* thread) { // If transitioning from running (0) to suspended (1) if (prevSuspend == 0) { - PCThreadData* data = nullptr; - - // Lock the global map to find our thread data - { - std::lock_guard mapLock(GetThreadDataMutex()); - auto it = GetThreadDataMap().find(thread); - if (it != GetThreadDataMap().end()) { - data = it->second.get(); - } - } + PCThreadData* data = GetThreadData(thread); if (data && data->started) { std::unique_lock threadLock(data->mtx); @@ -495,7 +459,6 @@ void OSExitThread(void* val) { currentThread->val = val; if (currentThread->attr & OS_THREAD_ATTR_DETACH) { - DequeueActive(currentThread); currentThread->state = 0; } else { currentThread->state = OS_THREAD_STATE_MORIBUND; @@ -507,10 +470,10 @@ void OSExitThread(void* val) { } void OSCancelThread(OSThread* thread) { + CRASH("OSCancelThread not implemented"); if (!thread) return; if (thread->attr & OS_THREAD_ATTR_DETACH) { - DequeueActive(thread); thread->state = 0; } else { thread->state = OS_THREAD_STATE_MORIBUND; @@ -521,11 +484,11 @@ void OSCancelThread(OSThread* thread) { } void OSDetachThread(OSThread* thread) { + CRASH("OSDetachThread not implemented"); if (!thread) return; thread->attr |= OS_THREAD_ATTR_DETACH; if (thread->state == OS_THREAD_STATE_MORIBUND) { - DequeueActive(thread); thread->state = 0; } OSWakeupThread(&thread->queueJoin); @@ -534,17 +497,14 @@ void OSDetachThread(OSThread* thread) { int OSJoinThread(OSThread* thread, void* val) { if (!thread) return 0; - if (!(thread->attr & OS_THREAD_ATTR_DETACH) && - thread->state != OS_THREAD_STATE_MORIBUND && - thread->queueJoin.head == nullptr) { - OSSleepThread(&thread->queueJoin); + if (!(thread->attr & OS_THREAD_ATTR_DETACH)) { + GetThreadData(thread)->nativeThread.join(); } if (thread->state == OS_THREAD_STATE_MORIBUND) { if (val) { *(s32*)val = (s32)(intptr_t)thread->val; } - DequeueActive(thread); thread->state = 0; return 1; }