diff --git a/nx/include/switch/kernel/detect.h b/nx/include/switch/kernel/detect.h index ded2ef9d..9061acce 100644 --- a/nx/include/switch/kernel/detect.h +++ b/nx/include/switch/kernel/detect.h @@ -7,37 +7,15 @@ #pragma once #include "../types.h" -extern bool g_IsAbove200; -extern bool g_IsAbove300; -extern bool g_IsAbove400; -extern bool g_IsAbove500; -extern bool g_IsAbove600; - /// Returns true if the kernel version is equal to or above 2.0.0. -static inline bool kernelAbove200(void) { - return g_IsAbove200; -} - +bool kernelAbove200(void); /// Returns true if the kernel version is equal to or above 3.0.0. -static inline bool kernelAbove300(void) { - return g_IsAbove300; -} - +bool kernelAbove300(void); /// Returns true if the kernel version is equal to or above 4.0.0. -static inline bool kernelAbove400(void) { - return g_IsAbove400; -} - +bool kernelAbove400(void); /// Returns true if the kernel version is equal to or above 5.0.0. -static inline bool kernelAbove500(void) { - return g_IsAbove500; -} - +bool kernelAbove500(void); /// Returns true if the kernel version is equal to or above 6.0.0. -static inline bool kernelAbove600(void) { - return g_IsAbove600; -} - +bool kernelAbove600(void); /// Returns true if the process has a debugger attached. bool detectDebugger(void); - diff --git a/nx/source/kernel/detect.c b/nx/source/kernel/detect.c index 0f4eed7b..34d1b20c 100644 --- a/nx/source/kernel/detect.c +++ b/nx/source/kernel/detect.c @@ -4,14 +4,26 @@ #include "kernel/mutex.h" #include "kernel/svc.h" -bool g_IsAbove200; -bool g_IsAbove300; -bool g_IsAbove400; -bool g_IsAbove500; -bool g_IsAbove600; +static bool g_IsAbove200; +static bool g_IsAbove300; +static bool g_IsAbove400; +static bool g_IsAbove500; +static bool g_IsAbove600; +static bool g_HasCached = 0; +static Mutex g_Mutex; -void detectSetup(void) +static void _CacheValues(void) { + if (__atomic_load_n(&g_HasCached, __ATOMIC_SEQ_CST)) + return; + + mutexLock(&g_Mutex); + + if (g_HasCached) { + mutexUnlock(&g_Mutex); + return; + } + u64 tmp; g_IsAbove200 = (svcGetInfo(&tmp, 12, INVALID_HANDLE, 0) != 0xF001); g_IsAbove300 = (svcGetInfo(&tmp, 18, INVALID_HANDLE, 0) != 0xF001); @@ -23,6 +35,35 @@ void detectSetup(void) g_IsAbove400 |= g_IsAbove500; g_IsAbove300 |= g_IsAbove400; g_IsAbove200 |= g_IsAbove300; + + __atomic_store_n(&g_HasCached, true, __ATOMIC_SEQ_CST); + + mutexUnlock(&g_Mutex); +} + +bool kernelAbove200(void) { + _CacheValues(); + return g_IsAbove200; +} + +bool kernelAbove300(void) { + _CacheValues(); + return g_IsAbove300; +} + +bool kernelAbove400(void) { + _CacheValues(); + return g_IsAbove400; +} + +bool kernelAbove500(void) { + _CacheValues(); + return g_IsAbove500; +} + +bool kernelAbove600(void) { + _CacheValues(); + return g_IsAbove600; } bool detectDebugger(void) { diff --git a/nx/source/runtime/init.c b/nx/source/runtime/init.c index 686cd124..e729c5ce 100644 --- a/nx/source/runtime/init.c +++ b/nx/source/runtime/init.c @@ -11,7 +11,6 @@ void* __stack_top; void NORETURN __nx_exit(Result rc, LoaderReturnFn retaddr); -void detectSetup(void); void virtmemSetup(void); void newlibSetup(void); void argvSetup(void); @@ -140,7 +139,6 @@ void __attribute__((weak)) __libnx_init(void* ctx, Handle main_thread, void* sav // Called by crt0. // Libnx initialization goes here. - detectSetup(); envSetup(ctx, main_thread, saved_lr); newlibSetup(); virtmemSetup();