Add Semaphore (#125)

This commit is contained in:
Kevoot 2018-06-30 18:45:41 -04:00 committed by fincs
parent 399a2ed21d
commit fbe2c1f2ce
3 changed files with 82 additions and 0 deletions

View File

@ -25,6 +25,7 @@ extern "C" {
#include "switch/kernel/rwlock.h"
#include "switch/kernel/condvar.h"
#include "switch/kernel/thread.h"
#include "switch/kernel/semaphore.h"
#include "switch/kernel/virtmem.h"
#include "switch/kernel/detect.h"
#include "switch/kernel/random.h"

View File

@ -0,0 +1,44 @@
/**
* @file semaphore.h
* @brief Thread synchronization based on Mutex.
* @author SciresM & Kevoot
* @copyright libnx Authors
*/
#pragma once
#include "mutex.h"
#include "condvar.h"
/// Semaphore structure.
typedef struct Semaphore
{
CondVar condvar; ///< Conditional Variable Object.
Mutex mutex; ///< Mutex Object.
u64 count; ///< Internal Counter.
} Semaphore;
/**
* @brief Initializes a semaphore and its internal counter.
* @param s Semaphore object.
* @param initial_count initial value for internal counter (typically the # of free resources).
*/
void semaphoreInit(Semaphore *s, u64 initial_count);
/**
* @brief Increments the Semaphore to allow other threads to continue.
* @param s Semaphore object.
*/
void semaphoreSignal(Semaphore *s);
/**
* @brief Decrements Semaphore and waits if 0.
* @param s Semaphore object.
*/
void semaphoreWait(Semaphore *s);
/**
* @brief Attempts to get lock without waiting.
* @param s Semaphore object.
* @return true if no wait and successful lock, false otherwise.
*/
bool semaphoreTryWait(Semaphore *s);

View File

@ -0,0 +1,37 @@
// Copyright 2018 Kevoot
#include "kernel/semaphore.h"
#include "kernel/svc.h"
void semaphoreInit(Semaphore *s, u64 initial_count) {
s->count = initial_count;
mutexInit(&s->mutex);
condvarInit(&s->condvar, &s->mutex);
}
void semaphoreSignal(Semaphore *s) {
mutexLock(&s->mutex);
s->count++;
condvarWakeOne(&s->condvar);
mutexUnlock(&s->mutex);
}
void semaphoreWait(Semaphore *s) {
mutexLock(&s->mutex);
// Wait until signalled.
while (!s->count) {
condvarWait(&s->condvar);
}
s->count--;
mutexUnlock(&s->mutex);
}
bool semaphoreTryWait(Semaphore *s) {
mutexLock(&s->mutex);
bool success = false;
// Check and immediately return success.
if (s->count) {
s->count--;
success = true;
}
return success;
}