mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-21 20:42:44 +02:00
Experimental implementation of condvars
This commit is contained in:
parent
ca6d017be9
commit
000a7f05c9
18
nx/include/switch/kernel/cond_var.h
Normal file
18
nx/include/switch/kernel/cond_var.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// Copyright 2018 plutoo
|
||||||
|
#include "../types.h"
|
||||||
|
#include "../kernel/mutex.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u32 tag;
|
||||||
|
Mutex* mutex;
|
||||||
|
} CondVar;
|
||||||
|
|
||||||
|
void condvarInit(CondVar* c, Mutex* m);
|
||||||
|
|
||||||
|
// When the wait-functions return, the mutex is acquired.
|
||||||
|
void condvarWaitTimeout(CondVar* c, u64 timeout);
|
||||||
|
void condvarWait(CondVar* c);
|
||||||
|
|
||||||
|
Result condvarWake(CondVar* c, int num);
|
||||||
|
Result condvarWakeOne(CondVar* c);
|
||||||
|
Result condvarWakeAll(CondVar* c);
|
@ -52,6 +52,8 @@ Result svcWaitSynchronization(s32* index, const Handle* handles, s32 handleCount
|
|||||||
Result svcCancelSynchronization(Handle thread);
|
Result svcCancelSynchronization(Handle thread);
|
||||||
Result svcArbitrateLock(u32 wait_tag, u32* tag_location, u32 self_tag);
|
Result svcArbitrateLock(u32 wait_tag, u32* tag_location, u32 self_tag);
|
||||||
Result svcArbitrateUnlock(u32* tag_location);
|
Result svcArbitrateUnlock(u32* tag_location);
|
||||||
|
Result svcWaitProcessWideKeyAtomic(u32* key, u32* tag_location, u32 self_tag, u64 timeout);
|
||||||
|
Result svcSignalProcessWideKey(u32* key, s32 num);
|
||||||
Result svcConnectToNamedPort(Handle* session, const char* name);
|
Result svcConnectToNamedPort(Handle* session, const char* name);
|
||||||
u64 svcGetSystemTick(void);
|
u64 svcGetSystemTick(void);
|
||||||
Result svcSendSyncRequest(Handle session);
|
Result svcSendSyncRequest(Handle session);
|
||||||
|
37
nx/source/kernel/cond_var.c
Normal file
37
nx/source/kernel/cond_var.c
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// Copyright 2018 plutoo
|
||||||
|
#include "types.h"
|
||||||
|
#include "result.h"
|
||||||
|
#include "kernel/svc.h"
|
||||||
|
#include "kernel/cond_var.h"
|
||||||
|
#include "../internal.h"
|
||||||
|
|
||||||
|
void condvarInit(CondVar* c, Mutex* m) {
|
||||||
|
c->tag = 0;
|
||||||
|
c->mutex = m;
|
||||||
|
}
|
||||||
|
|
||||||
|
void condvarWaitTimeout(CondVar* c, u64 timeout) {
|
||||||
|
Result rc;
|
||||||
|
|
||||||
|
rc = svcWaitProcessWideKeyAtomic(&c->tag, (u32*) c->mutex, getThreadVars()->handle, timeout);
|
||||||
|
|
||||||
|
// On timeout, we need to acquire it manually.
|
||||||
|
if (rc == 0xEA01)
|
||||||
|
mutexLock(c->mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void condvarWait(CondVar* c) {
|
||||||
|
return condvarWaitTimeout(c, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result condvarWake(CondVar* c, int num) {
|
||||||
|
return svcSignalProcessWideKey((u32*) &c->tag, num);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result condvarWakeOne(CondVar* c) {
|
||||||
|
return condvarWake(c, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result condvarWakeAll(CondVar* c) {
|
||||||
|
return condvarWake(c, -1);
|
||||||
|
}
|
@ -122,6 +122,16 @@ SVC_BEGIN svcArbitrateUnlock
|
|||||||
ret
|
ret
|
||||||
SVC_END
|
SVC_END
|
||||||
|
|
||||||
|
SVC_BEGIN svcWaitProcessWideKeyAtomic
|
||||||
|
svc 0x1c
|
||||||
|
ret
|
||||||
|
SVC_END
|
||||||
|
|
||||||
|
SVC_BEGIN svcSignalProcessWideKey
|
||||||
|
svc 0x1d
|
||||||
|
ret
|
||||||
|
SVC_END
|
||||||
|
|
||||||
SVC_BEGIN svcConnectToNamedPort
|
SVC_BEGIN svcConnectToNamedPort
|
||||||
str x0, [sp, #-16]!
|
str x0, [sp, #-16]!
|
||||||
svc 0x1F
|
svc 0x1F
|
||||||
|
Loading…
Reference in New Issue
Block a user