Implement devkitARM/newlib lock support & dynamic reent
This commit is contained in:
parent
1c18b0bffe
commit
05b8ce5b5d
@ -3,17 +3,13 @@
|
|||||||
* @brief Provides synchronization locks.
|
* @brief Provides synchronization locks.
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <sys/lock.h>
|
||||||
|
|
||||||
/// A light lock.
|
/// A light lock.
|
||||||
typedef s32 LightLock;
|
typedef _LOCK_T LightLock;
|
||||||
|
|
||||||
/// A recursive lock.
|
/// A recursive lock.
|
||||||
typedef struct
|
typedef _LOCK_RECURSIVE_T RecursiveLock;
|
||||||
{
|
|
||||||
LightLock lock; ///< Inner light lock.
|
|
||||||
u32 thread_tag; ///< Tag of the thread that currently has the lock.
|
|
||||||
u32 counter; ///< Lock count.
|
|
||||||
} RecursiveLock;
|
|
||||||
|
|
||||||
/// Performs a Data Synchronization Barrier operation.
|
/// Performs a Data Synchronization Barrier operation.
|
||||||
static inline void __dsb(void)
|
static inline void __dsb(void)
|
||||||
|
@ -4,10 +4,15 @@
|
|||||||
#include <3ds/svc.h>
|
#include <3ds/svc.h>
|
||||||
#include <sys/reent.h>
|
#include <sys/reent.h>
|
||||||
|
|
||||||
|
#define THREADVARS_MAGIC 0x21545624 // !TV$
|
||||||
#define FS_OVERRIDE_MAGIC 0x21465324 // !FS$
|
#define FS_OVERRIDE_MAGIC 0x21465324 // !FS$
|
||||||
|
|
||||||
|
// Keep this structure under 0x80 bytes
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
// Magic value used to check if the struct is initialized
|
||||||
|
u32 magic;
|
||||||
|
|
||||||
// Pointer to this thread's newlib state
|
// Pointer to this thread's newlib state
|
||||||
struct _reent* reent;
|
struct _reent* reent;
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ u32 __ctru_heap_size;
|
|||||||
u32 __ctru_linear_heap;
|
u32 __ctru_linear_heap;
|
||||||
u32 __ctru_linear_heap_size;
|
u32 __ctru_linear_heap_size;
|
||||||
|
|
||||||
void __attribute__((weak)) __system_allocateHeaps() {
|
void __attribute__((weak)) __system_allocateHeaps(void) {
|
||||||
u32 tmp=0;
|
u32 tmp=0;
|
||||||
|
|
||||||
if(envIsHomebrew()) {
|
if(envIsHomebrew()) {
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include <3ds/services/fs.h>
|
#include <3ds/services/fs.h>
|
||||||
#include <3ds/services/hid.h>
|
#include <3ds/services/hid.h>
|
||||||
|
|
||||||
void __attribute__((weak)) __appExit() {
|
void __attribute__((weak)) __appExit(void) {
|
||||||
// Exit services
|
// Exit services
|
||||||
sdmcExit();
|
sdmcExit();
|
||||||
fsExit();
|
fsExit();
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include <3ds/services/fs.h>
|
#include <3ds/services/fs.h>
|
||||||
#include <3ds/services/hid.h>
|
#include <3ds/services/hid.h>
|
||||||
|
|
||||||
void __attribute__((weak)) __appInit() {
|
void __attribute__((weak)) __appInit(void) {
|
||||||
// Initialize services
|
// Initialize services
|
||||||
srvInit();
|
srvInit();
|
||||||
aptInit();
|
aptInit();
|
||||||
|
@ -10,7 +10,7 @@ char** __system_argv;
|
|||||||
extern char* fake_heap_start;
|
extern char* fake_heap_start;
|
||||||
extern char* fake_heap_end;
|
extern char* fake_heap_end;
|
||||||
|
|
||||||
void __system_initArgv()
|
void __system_initArgv(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
const char* arglist = envGetSystemArgList();
|
const char* arglist = envGetSystemArgList();
|
||||||
|
@ -8,31 +8,27 @@
|
|||||||
|
|
||||||
void (*__system_retAddr)(void);
|
void (*__system_retAddr)(void);
|
||||||
|
|
||||||
void __system_allocateHeaps();
|
void __system_initSyscalls(void);
|
||||||
void __system_initArgv();
|
void __system_allocateHeaps(void);
|
||||||
void __appInit();
|
void __system_initArgv(void);
|
||||||
|
void __appInit(void);
|
||||||
|
|
||||||
|
Result __sync_init(void);
|
||||||
void __ctru_exit(int rc);
|
|
||||||
int __libctru_gtod(struct _reent *ptr, struct timeval *tp, struct timezone *tz);
|
|
||||||
|
|
||||||
Result __sync_init(void) __attribute__((weak));
|
|
||||||
|
|
||||||
void __attribute__((weak)) __libctru_init(void (*retAddr)(void))
|
void __attribute__((weak)) __libctru_init(void (*retAddr)(void))
|
||||||
{
|
{
|
||||||
|
// Store the return address
|
||||||
// Register newlib exit() syscall
|
|
||||||
__syscalls.exit = __ctru_exit;
|
|
||||||
__syscalls.gettod_r = __libctru_gtod;
|
|
||||||
|
|
||||||
__system_retAddr = envIsHomebrew() ? retAddr : NULL;
|
__system_retAddr = envIsHomebrew() ? retAddr : NULL;
|
||||||
|
|
||||||
if (__sync_init)
|
// Initialize the synchronization subsystem
|
||||||
__sync_init();
|
__sync_init();
|
||||||
|
|
||||||
|
// Initialize newlib support system calls
|
||||||
|
__system_initSyscalls();
|
||||||
|
|
||||||
|
// Allocate application and linear heaps
|
||||||
__system_allocateHeaps();
|
__system_allocateHeaps();
|
||||||
|
|
||||||
// Build argc/argv if present
|
// Build argc/argv if present
|
||||||
__system_initArgv();
|
__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