From 82b4f6327c0a80fe745ec9b7c161259c10a77020 Mon Sep 17 00:00:00 2001 From: PJB3005 Date: Sat, 14 Mar 2026 14:16:49 +0100 Subject: [PATCH] Assign names to threads Visible in debuggers etc --- include/dusk/os.h | 14 +++++++++ .../include/JSystem/JKernel/JKRThread.h | 4 +++ libs/JSystem/src/JKernel/JKRThread.cpp | 12 ++++++++ src/dusk/OSThread.cpp | 30 +++++++++++++++++++ src/m_Do/m_Do_DVDError.cpp | 7 +++++ src/m_Do/m_Do_MemCard.cpp | 5 ++++ src/m_Do/m_Do_dvd_thread.cpp | 4 +++ 7 files changed, 76 insertions(+) create mode 100644 include/dusk/os.h diff --git a/include/dusk/os.h b/include/dusk/os.h new file mode 100644 index 0000000000..180bdb9b1a --- /dev/null +++ b/include/dusk/os.h @@ -0,0 +1,14 @@ +#ifndef DUSK_OS_H +#define DUSK_OS_H + +#ifdef __cplusplus +extern "C" { +#endif + +void OSSetCurrentThreadName(const char* name); + +#ifdef __cplusplus +} +#endif + +#endif // DUSK_OS_H \ No newline at end of file diff --git a/libs/JSystem/include/JSystem/JKernel/JKRThread.h b/libs/JSystem/include/JSystem/JKernel/JKRThread.h index b58dc6232d..2830252281 100644 --- a/libs/JSystem/include/JSystem/JKernel/JKRThread.h +++ b/libs/JSystem/include/JSystem/JKernel/JKRThread.h @@ -132,6 +132,10 @@ public: static JSUList sThreadList; // static u8 sThreadList[12]; + +#if TARGET_PC + const char* mThreadName; +#endif }; class JKRIdleThread : public JKRThread { diff --git a/libs/JSystem/src/JKernel/JKRThread.cpp b/libs/JSystem/src/JKernel/JKRThread.cpp index 96dfd53499..6ba97e3d4a 100644 --- a/libs/JSystem/src/JKernel/JKRThread.cpp +++ b/libs/JSystem/src/JKernel/JKRThread.cpp @@ -7,6 +7,10 @@ #include "global.h" #include +#if TARGET_PC +#include "dusk/os.h" +#endif + JSUList JKRThread::sThreadList(0); void* JKRIdleThread::sThread; @@ -88,6 +92,14 @@ void JKRThread::setCommon_heapSpecified(JKRHeap* heap, u32 stack_size, int param } void* JKRThread::start(void* thread) { +#if TARGET_PC + auto& thd = *static_cast(thread); + if (thd.mThreadName == nullptr) { + thd.mThreadName = typeid(thd).name(); + } + OSSetCurrentThreadName(thd.mThreadName); +#endif + return ((JKRThread*)thread)->run(); } diff --git a/src/dusk/OSThread.cpp b/src/dusk/OSThread.cpp index 2d19139272..5301614c5b 100644 --- a/src/dusk/OSThread.cpp +++ b/src/dusk/OSThread.cpp @@ -17,6 +17,12 @@ #include #include "JSystem/JKernel/JKRHeap.h" +#include "dusk/os.h" + +#if _WIN32 +#define WIN32_LEAN_AND_MEAN 1 +#include +#endif // ============================================================================ // Malloc-based allocator to bypass JKRHeap operator new/delete @@ -744,6 +750,30 @@ OSInterruptMask __OSUnmaskInterrupts(OSInterruptMask mask) { return 0; } +void OSSetCurrentThreadName(const char* name) { + // "Why is this current thread only?", you might ask? + // Because macOS requires that. For some reason. + +#if _WIN32 + wchar_t buffer[256]; + const auto converted = MultiByteToWideChar( + CP_UTF8, + 0, + name, + -1, + buffer, + sizeof(buffer)/sizeof(wchar_t)); + if (converted == 0) { + CRASH("OSSetThreadName: MultiByteToWideChar failed"); + } + + const auto result = SetThreadDescription(GetCurrentThread(), buffer); + if (!SUCCEEDED(result)) { + CRASH("OSSetThreadName: SetThreadDescription failed"); + } +#endif +} + #ifdef __cplusplus } #endif diff --git a/src/m_Do/m_Do_DVDError.cpp b/src/m_Do/m_Do_DVDError.cpp index 4984ea22c7..62fd71ed21 100644 --- a/src/m_Do/m_Do_DVDError.cpp +++ b/src/m_Do/m_Do_DVDError.cpp @@ -14,6 +14,8 @@ #include #include +#include "dusk/os.h" + #if PLATFORM_GCN const int stack_size = 3072; #else @@ -65,6 +67,11 @@ static void mDoDvdErr_Watch(void*) { OSDisableInterrupts(); #endif #endif + +#if TARGET_PC + OSSetCurrentThreadName("DVD error thread"); +#endif + JKRThread(OSGetCurrentThread(), 0); JKRSetCurrentHeap(mDoExt_getAssertHeap()); diff --git a/src/m_Do/m_Do_MemCard.cpp b/src/m_Do/m_Do_MemCard.cpp index 919774d2e0..bbb94f2bcd 100644 --- a/src/m_Do/m_Do_MemCard.cpp +++ b/src/m_Do/m_Do_MemCard.cpp @@ -10,6 +10,7 @@ #include "m_Do/m_Do_MemCardRWmng.h" #include "m_Do/m_Do_Reset.h" #include "os_report.h" +#include "dusk/os.h" #if PLATFORM_WII || PLATFORM_SHIELD #include @@ -866,6 +867,10 @@ mDoMemCd_Ctrl_c g_mDoMemCd_control; static int mDoMemCd_main(void*) { JKRThread(OSGetCurrentThread(), 0); +#if TARGET_PC + OSSetCurrentThreadName("MemCardThread"); +#endif + JKRSetCurrentHeap(mDoExt_getAssertHeap()); g_mDoMemCd_control.main(); diff --git a/src/m_Do/m_Do_dvd_thread.cpp b/src/m_Do/m_Do_dvd_thread.cpp index 6ea1cf99f7..c5f982bc9d 100644 --- a/src/m_Do/m_Do_dvd_thread.cpp +++ b/src/m_Do/m_Do_dvd_thread.cpp @@ -10,6 +10,7 @@ #include "JSystem/JKernel/JKRDvdRipper.h" #include "JSystem/JKernel/JKRExpHeap.h" #include "JSystem/JKernel/JKRMemArchive.h" +#include "dusk/os.h" #include "m_Do/m_Do_Reset.h" #include "m_Do/m_Do_controller_pad.h" #include "m_Do/m_Do_ext.h" @@ -17,6 +18,9 @@ s32 mDoDvdThd::main(void* param_0) { JKRThread(OSGetCurrentThread(), 0); +#if TARGET_PC + OSSetCurrentThreadName("DVD thread"); +#endif JKRSetCurrentHeap(mDoExt_getAssertHeap()); mDoDvdThd_param_c* param = static_cast(param_0); param->mainLoop();