/************************************************************************/ /* */ /* 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