* @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)
#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;
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()) {
#include <3ds/services/fs.h>
#include <3ds/services/hid.h>
-void __attribute__((weak)) __appExit() {
+void __attribute__((weak)) __appExit(void) {
// Exit services
sdmcExit();
fsExit();
#include <3ds/services/fs.h>
#include <3ds/services/hid.h>
-void __attribute__((weak)) __appInit() {
+void __attribute__((weak)) __appInit(void) {
// Initialize services
srvInit();
aptInit();
extern char* fake_heap_start;
extern char* fake_heap_end;
-void __system_initArgv()
+void __system_initArgv(void)
{
int i;
const char* arglist = envGetSystemArgList();
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();
-
}
--- /dev/null
+#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;
+}