]> Chaos Git - corbenik/ctrulib.git/commitdiff
Implement devkitARM/newlib lock support & dynamic reent
authorfincs <fincs.alt1@gmail.com>
Sat, 21 Nov 2015 13:14:56 +0000 (14:14 +0100)
committerfincs <fincs.alt1@gmail.com>
Mon, 7 Dec 2015 10:43:54 +0000 (11:43 +0100)
libctru/include/3ds/synchronization.h
libctru/source/internal.h
libctru/source/system/allocateHeaps.c
libctru/source/system/appExit.c
libctru/source/system/appInit.c
libctru/source/system/initArgv.c
libctru/source/system/initSystem.c
libctru/source/system/syscalls.c [new file with mode: 0644]

index 05d94c6506b38cf86e6c66ad9c389b1e1a7c87a2..d6dc06805988697b1a225d41ae805a6e8dd1581e 100644 (file)
@@ -3,17 +3,13 @@
  * @brief Provides synchronization locks.
  */
 #pragma once
+#include <sys/lock.h>
 
 /// A light lock.
-typedef s32 LightLock;
+typedef _LOCK_T LightLock;
 
 /// A recursive lock.
-typedef struct
-{
-       LightLock lock; ///< Inner light lock.
-       u32 thread_tag; ///< Tag of the thread that currently has the lock.
-       u32 counter;    ///< Lock count.
-} RecursiveLock;
+typedef _LOCK_RECURSIVE_T RecursiveLock;
 
 /// Performs a Data Synchronization Barrier operation.
 static inline void __dsb(void)
index 7bf09ec5c39882d70e4848a55422758466f4333c..53a4c9f1bb0a4d938b61c36ea9e54f9e98dbdcac 100644 (file)
@@ -4,10 +4,15 @@
 #include <3ds/svc.h>
 #include <sys/reent.h>
 
+#define THREADVARS_MAGIC  0x21545624 // !TV$
 #define FS_OVERRIDE_MAGIC 0x21465324 // !FS$
 
+// Keep this structure under 0x80 bytes
 typedef struct
 {
+       // Magic value used to check if the struct is initialized
+       u32 magic;
+
        // Pointer to this thread's newlib state
        struct _reent* reent;
 
index 0d7859ce6bf5f607799a3537292c1426b5669e09..02c9964351f565740fc7a4833c083095e66e36cc 100644 (file)
@@ -11,7 +11,7 @@ u32 __ctru_heap_size;
 u32 __ctru_linear_heap;
 u32 __ctru_linear_heap_size;
 
-void __attribute__((weak)) __system_allocateHeaps() {
+void __attribute__((weak)) __system_allocateHeaps(void) {
        u32 tmp=0;
 
        if(envIsHomebrew()) {
index d2e9d4854d8a4e887b94d39a295984ce86b071f2..9ac6c0841a2059beee0e4669291438d8ab31200f 100644 (file)
@@ -6,7 +6,7 @@
 #include <3ds/services/fs.h>
 #include <3ds/services/hid.h>
 
-void __attribute__((weak)) __appExit() {
+void __attribute__((weak)) __appExit(void) {
        // Exit services
        sdmcExit();
        fsExit();
index c3213e05aa7e8d81d7a2955bfa46a6f2cca50de2..d9c43014ebb512a0f054a6fc6449cb528bf86a24 100644 (file)
@@ -6,7 +6,7 @@
 #include <3ds/services/fs.h>
 #include <3ds/services/hid.h>
 
-void __attribute__((weak)) __appInit() {
+void __attribute__((weak)) __appInit(void) {
        // Initialize services
        srvInit();
        aptInit();
index d566b000397c18eb5aff82493aee919fdd7a4f07..5e615826698324aa5e4835910d3a8238e09bc081 100644 (file)
@@ -10,7 +10,7 @@ char** __system_argv;
 extern char* fake_heap_start;
 extern char* fake_heap_end;
 
-void __system_initArgv()
+void __system_initArgv(void)
 {
        int i;
        const char* arglist = envGetSystemArgList();
index 0d0ac97ee66583b0f2ecb012dc25bb59be994220..236fbd0021403f40a6c58a71416abd0fcc4e4ba0 100644 (file)
@@ -8,31 +8,27 @@
 
 void (*__system_retAddr)(void);
 
-void __system_allocateHeaps();
-void __system_initArgv();
-void __appInit();
+void __system_initSyscalls(void);
+void __system_allocateHeaps(void);
+void __system_initArgv(void);
+void __appInit(void);
 
-
-void __ctru_exit(int rc);
-int __libctru_gtod(struct _reent *ptr, struct timeval *tp, struct timezone *tz);
-
-Result __sync_init(void) __attribute__((weak));
+Result __sync_init(void);
 
 void __attribute__((weak)) __libctru_init(void (*retAddr)(void))
 {
-
-       // Register newlib exit() syscall
-       __syscalls.exit = __ctru_exit;
-    __syscalls.gettod_r = __libctru_gtod;
-
+       // Store the return address
        __system_retAddr = envIsHomebrew() ? retAddr : NULL;
 
-       if (__sync_init)
-               __sync_init();
+       // Initialize the synchronization subsystem
+       __sync_init();
+
+       // Initialize newlib support system calls
+       __system_initSyscalls();
 
+       // Allocate application and linear heaps
        __system_allocateHeaps();
 
        // Build argc/argv if present
        __system_initArgv();
-
 }
diff --git a/libctru/source/system/syscalls.c b/libctru/source/system/syscalls.c
new file mode 100644 (file)
index 0000000..3cb5734
--- /dev/null
@@ -0,0 +1,48 @@
+#include <sys/iosupport.h>
+#include <sys/time.h>
+#include <sys/lock.h>
+#include <sys/reent.h>
+#include <string.h>
+
+#include <3ds/types.h>
+#include <3ds/svc.h>
+#include <3ds/env.h>
+#include <3ds/synchronization.h>
+#include "../internal.h"
+
+void __ctru_exit(int rc);
+int __libctru_gtod(struct _reent *ptr, struct timeval *tp, struct timezone *tz);
+
+static struct _reent* __ctru_get_reent()
+{
+       ThreadVars* tv = getThreadVars();
+       if (tv->magic != THREADVARS_MAGIC)
+       {
+               svcBreak(USERBREAK_PANIC);
+               for (;;);
+       }
+       return tv->reent;
+}
+
+void __system_initSyscalls(void)
+{
+       // Register newlib syscalls
+       __syscalls.exit     = __ctru_exit;
+       __syscalls.gettod_r = __libctru_gtod;
+       __syscalls.getreent = __ctru_get_reent;
+
+       // Register locking syscalls
+       __syscalls.lock_init                  = LightLock_Init;
+       __syscalls.lock_acquire               = LightLock_Lock;
+       __syscalls.lock_try_acquire           = LightLock_TryLock;
+       __syscalls.lock_release               = LightLock_Unlock;
+       __syscalls.lock_init_recursive        = RecursiveLock_Init;
+       __syscalls.lock_acquire_recursive     = RecursiveLock_Lock;
+       __syscalls.lock_try_acquire_recursive = RecursiveLock_TryLock;
+       __syscalls.lock_release_recursive     = RecursiveLock_Unlock;
+
+       // Initialize thread vars for the main thread
+       ThreadVars* tv = getThreadVars();
+       tv->magic = THREADVARS_MAGIC;
+       tv->reent = _impure_ptr;
+}