mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-22 13:02:38 +02:00
Integrate newlib locks with libnx (R)Mutex (untested, incomplete)
This commit is contained in:
parent
757349c5c4
commit
f27685b7b3
@ -1,13 +1,9 @@
|
|||||||
// Copyright 2017 plutoo
|
// Copyright 2017 plutoo
|
||||||
typedef struct {
|
#pragma once
|
||||||
u32 Tag;
|
#include <sys/lock.h>
|
||||||
} Mutex;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef _LOCK_T Mutex;
|
||||||
u32 Owner;
|
typedef _LOCK_RECURSIVE_T RMutex;
|
||||||
Mutex Lock;
|
|
||||||
size_t Count;
|
|
||||||
} RMutex;
|
|
||||||
|
|
||||||
void mutexLock(Mutex* m);
|
void mutexLock(Mutex* m);
|
||||||
void mutexUnlock(Mutex* m);
|
void mutexUnlock(Mutex* m);
|
||||||
|
@ -11,7 +11,7 @@ static u32 _GetTag() {
|
|||||||
|
|
||||||
void mutexLock(Mutex* m) {
|
void mutexLock(Mutex* m) {
|
||||||
u32 self = _GetTag();
|
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) {
|
while (1) {
|
||||||
if (cur == 0) {
|
if (cur == 0) {
|
||||||
@ -26,44 +26,44 @@ void mutexLock(Mutex* m) {
|
|||||||
|
|
||||||
if (cur & HAS_LISTENERS) {
|
if (cur & HAS_LISTENERS) {
|
||||||
// The flag is already set, we can use the syscall.
|
// 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 {
|
else {
|
||||||
// The flag is not set, we need to set it.
|
// 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) {
|
if (old == cur) {
|
||||||
// Flag was set successfully.
|
// 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) {
|
void mutexUnlock(Mutex* m) {
|
||||||
u32 self = _GetTag();
|
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) {
|
if (old & HAS_LISTENERS) {
|
||||||
svcArbitrateUnlock(&m->Tag);
|
svcArbitrateUnlock((u32*)m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rmutexLock(RMutex* m) {
|
void rmutexLock(RMutex* m) {
|
||||||
if (m->Owner == _GetTag()) {
|
if (m->thread_tag == _GetTag()) {
|
||||||
m->Count++;
|
m->counter++;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mutexLock(&m->Lock);
|
mutexLock(&m->lock);
|
||||||
m->Owner = _GetTag();
|
m->thread_tag = _GetTag();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rmutexUnlock(RMutex* m) {
|
void rmutexUnlock(RMutex* m) {
|
||||||
if (--m->Count == 0) {
|
if (--m->counter == 0) {
|
||||||
m->Owner = 0;
|
m->thread_tag = 0;
|
||||||
mutexUnlock(&m->Lock);
|
mutexUnlock(&m->lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ void __attribute__((weak)) __libnx_init(void)
|
|||||||
__libc_init_array();
|
__libc_init_array();
|
||||||
}
|
}
|
||||||
|
|
||||||
void __attribute__((weak)) NORETURN __libnx_exit(void)
|
void __attribute__((weak)) NORETURN __libnx_exit(int rc)
|
||||||
{
|
{
|
||||||
// Call destructors.
|
// Call destructors.
|
||||||
void __libc_fini_array(void);
|
void __libc_fini_array(void);
|
||||||
|
@ -4,15 +4,15 @@
|
|||||||
#include <sys/lock.h>
|
#include <sys/lock.h>
|
||||||
#include <sys/reent.h>
|
#include <sys/reent.h>
|
||||||
|
|
||||||
void __attribute__((weak)) NORETURN __libnx_exit(void);
|
void __attribute__((weak)) NORETURN __libnx_exit(int rc);
|
||||||
|
|
||||||
|
|
||||||
static void NORETURN _ExitImpl(int rc) {
|
|
||||||
__libnx_exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
void newlibSetup() {
|
void newlibSetup() {
|
||||||
void exitImpl(int rc);
|
// Register newlib syscalls
|
||||||
__syscalls.exit = _ExitImpl;
|
__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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user