From f27685b7b38ef115e1eff4147a40e44f5dddd3c2 Mon Sep 17 00:00:00 2001 From: fincs Date: Wed, 8 Nov 2017 18:54:23 +0100 Subject: [PATCH] Integrate newlib locks with libnx (R)Mutex (untested, incomplete) --- nx/include/switch/kernel/mutex.h | 12 ++++-------- nx/source/kernel/mutex.c | 28 ++++++++++++++-------------- nx/source/system/init.c | 2 +- nx/source/system/newlib.c | 16 ++++++++-------- 4 files changed, 27 insertions(+), 31 deletions(-) diff --git a/nx/include/switch/kernel/mutex.h b/nx/include/switch/kernel/mutex.h index 05b61b14..dbc79b7d 100644 --- a/nx/include/switch/kernel/mutex.h +++ b/nx/include/switch/kernel/mutex.h @@ -1,13 +1,9 @@ // Copyright 2017 plutoo -typedef struct { - u32 Tag; -} Mutex; +#pragma once +#include -typedef struct { - u32 Owner; - Mutex Lock; - size_t Count; -} RMutex; +typedef _LOCK_T Mutex; +typedef _LOCK_RECURSIVE_T RMutex; void mutexLock(Mutex* m); void mutexUnlock(Mutex* m); diff --git a/nx/source/kernel/mutex.c b/nx/source/kernel/mutex.c index e13f0e35..103108c6 100644 --- a/nx/source/kernel/mutex.c +++ b/nx/source/kernel/mutex.c @@ -11,7 +11,7 @@ static u32 _GetTag() { void mutexLock(Mutex* m) { u32 self = _GetTag(); - u32 cur = __sync_val_compare_and_swap(&m->Tag, 0, self); + u32 cur = __sync_val_compare_and_swap(m, 0, self); while (1) { if (cur == 0) { @@ -26,44 +26,44 @@ void mutexLock(Mutex* m) { if (cur & HAS_LISTENERS) { // The flag is already set, we can use the syscall. - svcArbitrateLock(cur &~ HAS_LISTENERS, &m->Tag, self); + svcArbitrateLock(cur &~ HAS_LISTENERS, (u32*)m, self); } else { // The flag is not set, we need to set it. - u32 old = __sync_val_compare_and_swap(&m->Tag, cur, cur | HAS_LISTENERS); + u32 old = __sync_val_compare_and_swap(m, cur, cur | HAS_LISTENERS); if (old == cur) { // Flag was set successfully. - svcArbitrateLock(cur &~ HAS_LISTENERS, &m->Tag, self); + svcArbitrateLock(cur &~ HAS_LISTENERS, (u32*)m, self); } } - cur = __sync_val_compare_and_swap(&m->Tag, 0, self); + cur = __sync_val_compare_and_swap(m, 0, self); } } void mutexUnlock(Mutex* m) { u32 self = _GetTag(); - u32 old = __sync_val_compare_and_swap(&m->Tag, self, 0); + u32 old = __sync_val_compare_and_swap(m, self, 0); if (old & HAS_LISTENERS) { - svcArbitrateUnlock(&m->Tag); + svcArbitrateUnlock((u32*)m); } } void rmutexLock(RMutex* m) { - if (m->Owner == _GetTag()) { - m->Count++; + if (m->thread_tag == _GetTag()) { + m->counter++; } else { - mutexLock(&m->Lock); - m->Owner = _GetTag(); + mutexLock(&m->lock); + m->thread_tag = _GetTag(); } } void rmutexUnlock(RMutex* m) { - if (--m->Count == 0) { - m->Owner = 0; - mutexUnlock(&m->Lock); + if (--m->counter == 0) { + m->thread_tag = 0; + mutexUnlock(&m->lock); } } diff --git a/nx/source/system/init.c b/nx/source/system/init.c index 1d7d9094..7a832310 100644 --- a/nx/source/system/init.c +++ b/nx/source/system/init.c @@ -63,7 +63,7 @@ void __attribute__((weak)) __libnx_init(void) __libc_init_array(); } -void __attribute__((weak)) NORETURN __libnx_exit(void) +void __attribute__((weak)) NORETURN __libnx_exit(int rc) { // Call destructors. void __libc_fini_array(void); diff --git a/nx/source/system/newlib.c b/nx/source/system/newlib.c index 537f5431..cc9cd572 100644 --- a/nx/source/system/newlib.c +++ b/nx/source/system/newlib.c @@ -4,15 +4,15 @@ #include #include -void __attribute__((weak)) NORETURN __libnx_exit(void); - - -static void NORETURN _ExitImpl(int rc) { - __libnx_exit(); -} +void __attribute__((weak)) NORETURN __libnx_exit(int rc); void newlibSetup() { - void exitImpl(int rc); - __syscalls.exit = _ExitImpl; + // Register newlib syscalls + __syscalls.exit = __libnx_exit; + // Register locking syscalls + __syscalls.lock_acquire = mutexLock; + __syscalls.lock_release = mutexUnlock; + __syscalls.lock_acquire_recursive = rmutexLock; + __syscalls.lock_release_recursive = rmutexUnlock; }