diff --git a/nx/include/switch/kernel/thread.h b/nx/include/switch/kernel/thread.h index 47d57868..89cc83bc 100644 --- a/nx/include/switch/kernel/thread.h +++ b/nx/include/switch/kernel/thread.h @@ -91,6 +91,12 @@ Result threadResume(Thread* t); */ Result threadDumpContext(ThreadContext* ctx, Thread* t); +/** + * @brief Gets a pointer to the current thread structure. + * @return Thread information structure. + */ +Thread *threadGetSelf(void); + /** * @brief Gets the raw handle to the current thread. * @return The current thread's handle. diff --git a/nx/source/kernel/thread.c b/nx/source/kernel/thread.c index a4805066..08617cfa 100644 --- a/nx/source/kernel/thread.c +++ b/nx/source/kernel/thread.c @@ -9,6 +9,7 @@ #include "kernel/thread.h" #include "kernel/wait.h" #include "services/fatal.h" +#include "runtime/env.h" #include "../internal.h" #define USER_TLS_BEGIN 0x108 @@ -23,6 +24,8 @@ extern u8 __tls_end[]; static Mutex g_threadMutex; static Thread* g_threadList; +static Thread g_mainThread; + static u64 g_tlsUsageMask; static void (* g_tlsDestructors[NUM_TLS_SLOTS])(void*); @@ -60,6 +63,33 @@ static void _EntryWrap(ThreadEntryArgs* args) { threadExit(); } +void __libnx_init_thread(void) { + g_mainThread.handle = envGetMainThreadHandle(); + + MemoryInfo mem_info = {0}; + u32 page_info; + svcQueryMemory(&mem_info, &page_info, (u64)(&mem_info)); + + // Set stack. + g_mainThread.owns_stack_mem = false; + g_mainThread.stack_mem = NULL; + g_mainThread.stack_mirror = (void*)mem_info.addr; + g_mainThread.stack_sz = mem_info.size; + + // Set the TLS array. + mutexLock(&g_threadMutex); + g_mainThread.tls_array = (void**)((u8*)armGetTls() + USER_TLS_BEGIN); + g_mainThread.prev_next = &g_threadList; + g_mainThread.next = g_threadList; + if (g_threadList) + g_threadList->prev_next = &g_mainThread.next; + g_threadList = &g_mainThread; + mutexUnlock(&g_threadMutex); + + // Set thread_ptr. + getThreadVars()->thread_ptr = &g_mainThread; +} + Result threadCreate( Thread* t, ThreadFunc entry, void* arg, void* stack_mem, size_t stack_sz, int prio, int cpuid) @@ -230,6 +260,10 @@ Result threadDumpContext(ThreadContext* ctx, Thread* t) { return svcGetThreadContext3(ctx, t->handle); } +Thread *threadGetSelf(void) { + return getThreadVars()->thread_ptr; +} + Handle threadGetCurHandle(void) { return getThreadVars()->handle; } diff --git a/nx/source/runtime/init.c b/nx/source/runtime/init.c index 3aff48fc..e0cb9d9d 100644 --- a/nx/source/runtime/init.c +++ b/nx/source/runtime/init.c @@ -16,6 +16,7 @@ void NORETURN __nx_exit(Result rc, LoaderReturnFn retaddr); void virtmemSetup(void); void newlibSetup(void); void argvSetup(void); +void __libnx_init_thread(void); void __libnx_init_time(void); void __libnx_init_cwd(void); @@ -174,6 +175,7 @@ void __attribute__((weak)) __libnx_init(void* ctx, Handle main_thread, void* sav newlibSetup(); virtmemSetup(); __libnx_initheap(); + __libnx_init_thread(); // Build argc/argv if present argvSetup();