Implement devkitARM/newlib lock support & dynamic reent
This commit is contained in:
parent
1c18b0bffe
commit
05b8ce5b5d
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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()) {
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
||||
}
|
||||
|
48
libctru/source/system/syscalls.c
Normal file
48
libctru/source/system/syscalls.c
Normal file
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user