diff options
Diffstat (limited to 'sem.c')
| -rw-r--r-- | sem.c | 78 |
1 files changed, 78 insertions, 0 deletions
@@ -0,0 +1,78 @@ +/************************************************************************/ +/* */ +/* File: sem.c */ +/* Description: semaphore P and V operations. */ +/* Version: 1.0 */ +/* Author: Otto Mattik */ +/* */ +/* (C)Copyright Otto Mattik 2014-2021. */ +/* */ +/* This file is a part of 'armen' (a tiny operating system). */ +/* 'armen' is distributed under the CeCILL-V2.1 licence. For more */ +/* details about this licence, please visit the website cecill.info */ +/* */ +/************************************************************************/ + +#ifdef USE_SEM + +#include "core.h" + +/* + * initialize a semaphore + * + * input: + * sem address of semaphore + * value initial value for semaphore + * output: +*/ +void sem_init( sem_t* sem, uint8_t value ) +{ + ((_sem_t*)sem)->lock = 0; + ((_sem_t*)sem)->value = + ((_sem_t*)sem)->count = value; +} + +/* + * P operation + * + * input: + * sem address of semaphore + * output: + * O if success, otherwise -1 +*/ +void sem_wait( sem_t* sem ) +{ + while( test_and_set( sem ) != 0 ) ; + if( ((_sem_t*)sem)->count == 0 ) + { + ((_sem_t*)sem)->lock = 0; + _threads[_cur_thread].sem = sem; + wait_event( EVENT_SEM ); + } + else + { + --((_sem_t*)sem)->count; + ((_sem_t*)sem)->lock = 0; + } +} + +/* + * V operation + * + * input: + * sem address of semaphore + * output: + * O if success, otherwise -1 +*/ +void sem_post( sem_t* sem ) +{ + while( test_and_set( sem ) != 0 ) ; + if( ((_sem_t*)sem)->count != ((_sem_t*)sem)->value ) + { + ++((_sem_t*)sem)->count; + _wakeup( EVENT_SEM, sem ); + } + ((_sem_t*)sem)->lock = 0; +} + +#endif |
