Change CondVar API to have the mutex be passed to condvarWait* instead of condvarInit

This commit is contained in:
fincs 2018-08-05 14:31:31 +02:00
parent 062ef2b188
commit 1e349b6ce8
4 changed files with 24 additions and 28 deletions

View File

@ -6,39 +6,41 @@
*/
#pragma once
#include "../types.h"
#include "../kernel/svc.h"
#include "../kernel/mutex.h"
/// Condition variable structure.
typedef struct {
u32 tag;
Mutex* mutex;
} CondVar;
/// Condition variable.
typedef u32 CondVar;
/**
* @brief Initializes a condition variable.
* @param[in] c Condition variable object.
* @param[in] m Mutex object to use inside the condition variable.
*/
void condvarInit(CondVar* c, Mutex* m);
static inline void condvarInit(CondVar* c)
{
*c = 0;
}
/**
* @brief Waits on a condition variable with a timeout.
* @param[in] c Condition variable object.
* @param[in] m Mutex object to use inside the condition variable.
* @param[in] timeout Timeout in nanoseconds.
* @return Result code (0xEA01 on timeout).
* @remark On function return, the underlying mutex is acquired.
*/
Result condvarWaitTimeout(CondVar* c, u64 timeout);
Result condvarWaitTimeout(CondVar* c, Mutex* m, u64 timeout);
/**
* @brief Waits on a condition variable.
* @param[in] c Condition variable object.
* @param[in] m Mutex object to use inside the condition variable.
* @return Result code.
* @remark On function return, the underlying mutex is acquired.
*/
static inline Result condvarWait(CondVar* c)
static inline Result condvarWait(CondVar* c, Mutex* m)
{
return condvarWaitTimeout(c, -1ull);
return condvarWaitTimeout(c, m, U64_MAX);
}
/**
@ -47,7 +49,10 @@ static inline Result condvarWait(CondVar* c)
* @param[in] num Maximum number of threads to wake up (or -1 to wake them all up).
* @return Result code.
*/
Result condvarWake(CondVar* c, int num);
static inline Result condvarWake(CondVar* c, int num)
{
return svcSignalProcessWideKey(c, num);
}
/**
* @brief Wakes up a single thread waiting on a condition variable.

View File

@ -12,9 +12,9 @@
/// Semaphore structure.
typedef struct Semaphore
{
CondVar condvar; ///< Conditional Variable Object.
Mutex mutex; ///< Mutex Object.
u64 count; ///< Internal Counter.
CondVar condvar; ///< Condition variable object.
Mutex mutex; ///< Mutex object.
u64 count; ///< Internal counter.
} Semaphore;
/**

View File

@ -5,23 +5,14 @@
#include "kernel/condvar.h"
#include "../internal.h"
void condvarInit(CondVar* c, Mutex* m) {
c->tag = 0;
c->mutex = m;
}
Result condvarWaitTimeout(CondVar* c, u64 timeout) {
Result condvarWaitTimeout(CondVar* c, Mutex* m, u64 timeout) {
Result rc;
rc = svcWaitProcessWideKeyAtomic((u32*) c->mutex, &c->tag, getThreadVars()->handle, timeout);
rc = svcWaitProcessWideKeyAtomic((u32*)m, c, getThreadVars()->handle, timeout);
// On timeout, we need to acquire it manually.
if (rc == 0xEA01)
mutexLock(c->mutex);
mutexLock(m);
return rc;
}
Result condvarWake(CondVar* c, int num) {
return svcSignalProcessWideKey((u32*) &c->tag, num);
}

View File

@ -5,7 +5,7 @@
void semaphoreInit(Semaphore *s, u64 initial_count) {
s->count = initial_count;
mutexInit(&s->mutex);
condvarInit(&s->condvar, &s->mutex);
condvarInit(&s->condvar);
}
void semaphoreSignal(Semaphore *s) {
@ -19,7 +19,7 @@ void semaphoreWait(Semaphore *s) {
mutexLock(&s->mutex);
// Wait until signalled.
while (!s->count) {
condvarWait(&s->condvar);
condvarWait(&s->condvar, &s->mutex);
}
s->count--;
mutexUnlock(&s->mutex);