diff --git a/nx/include/switch.h b/nx/include/switch.h index 2ed024d1..c23aeea2 100644 --- a/nx/include/switch.h +++ b/nx/include/switch.h @@ -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" diff --git a/nx/include/switch/kernel/semaphore.h b/nx/include/switch/kernel/semaphore.h new file mode 100644 index 00000000..8b862459 --- /dev/null +++ b/nx/include/switch/kernel/semaphore.h @@ -0,0 +1,29 @@ +// Copyright 2018 Kevoot + +#ifndef __SEMAPHORE_H +#define __SEMAPHORE_H + +#include "mutex.h" + +#define SEM_DOWN false +#define SEM_UP true + +#define EBUSY 1 + +typedef struct sem_t +{ + bool flag; + Mutex mutex; +} sem_t; + +void sem_init(sem_t *); +void sem_uninit(sem_t *); +/* TODO */ +void set_post(sem_t *); +void sem_up(sem_t *); +void sem_down(sem_t *); +void sem_wait(sem_t *); +void sem_waitup(sem_t *); +bool sem_isup(sem_t *); + +#endif \ No newline at end of file diff --git a/nx/source/kernel/semaphore.c b/nx/source/kernel/semaphore.c new file mode 100644 index 00000000..fe0df97f --- /dev/null +++ b/nx/source/kernel/semaphore.c @@ -0,0 +1,58 @@ +// Copyright 2018 Kevoot +#include "kernel/semaphore.h" +#include "kernel/svc.h" + +void _priv_sem_wait(sem_t *sem, bool flag); + +void sem_down(sem_t *sem) { + mutexLock(&sem->mutex); + sem->flag = SEM_DOWN; + mutexUnlock(&sem->mutex); +} + +void sem_init(sem_t *sem) { + sem->flag = SEM_DOWN; + mutexInit(&sem->mutex); +} + +void sem_uninit(sem_t *sem) { + sem->flag = SEM_DOWN; +} + +void sem_up(sem_t *sem) { + mutexLock(&sem->mutex); + sem->flag = SEM_UP; + mutexUnlock(&sem->mutex); +} + +void sem_wait(sem_t *sem) { + _priv_sem_wait(sem, SEM_DOWN); +} + +void sem_waitup(sem_t *sem) { + _priv_sem_wait(sem, SEM_UP); +} + +bool sem_isup(sem_t *sem) { + bool flag; + + mutexLock(&sem->mutex); + flag = sem->flag; + mutexUnlock(&sem->mutex); + + return flag; +} + +void _priv_sem_wait(sem_t *sem, bool flag) { + while (true) { + mutexLock(&sem->mutex); + + if (sem->flag == flag) { + mutexUnlock(&sem->mutex); + break; + } + + mutexUnlock(&sem->mutex); + svcSleepThread(1000000); + } +} \ No newline at end of file