diff --git a/avr-threads/src/cs.c b/avr-threads/src/cs.c new file mode 100644 --- /dev/null +++ b/avr-threads/src/cs.c @@ -0,0 +1,84 @@ +/** +\file cs.c + +Counting semaphores are described at many places. They are ideal to +synchronize buffer access between threads. +The basic operations as described by Dijkstra are P (here: request) +and V (here: release). +Creation of a semaphore is done by defining a static variable +of the type Sema_cs. Due to the initialization behavior of the compiler, +the semaphore starts with the value 0 - this means that nobody is currently +waiting for it and no ressource is free. +To initialize a semaphore with a value greater than 0, just perform the +desired release operations at system startup. +The thread blocking, unblocking and queue management is realized with the +event faculity of avr-threads. + +Make shure that the components of the struct Sema_cs is initialized to zero! + +\brief Counting semaphores + +\author R. Müller + +*/ + +#include +#include + +#include "cs.h" + +static volatile avr_thread_mutex_basic mutex; //< mutex for this module + +/*! +Request a semaphore + +If the current (internal) value of the given semaphore +is greater than 0 +the value is decremented and the function returns. +If the value has reached the low bound; the calling task becomes blocked, until +a corresponding release occurs + +\param s the semaphore to work with +*/ +void request_cs(struct Sema_cs * s) +{ + avr_thread_mutex_basic_gain(&mutex); + + if (s->value <= 0) + { + s->value --; + avr_thread_mutex_basic_release(&mutex); + avr_thread_event_wait_and_clear(&(s->e),0); + } + else + { + s->value --; + avr_thread_mutex_basic_release(&mutex); + } +} + +/*! +Release a semaphore + +If the current internal value of the given semaphore is less than 0 +one waiting thread will become runnable again + +\param s the semaphore to work with +*/ +void release_cs(struct Sema_cs * s) +{ + avr_thread_mutex_basic_gain(&mutex); + + if (s->value < 0) + { + s->value ++; + avr_thread_event_set_wake_one(&(s->e)); + avr_thread_mutex_basic_release(&mutex); + } + else + { + s->value ++; + avr_thread_mutex_basic_release(&mutex); + } +} + diff --git a/avr-threads/src/cs.h b/avr-threads/src/cs.h new file mode 100644 --- /dev/null +++ b/avr-threads/src/cs.h @@ -0,0 +1,26 @@ +/** +\file cs.h + +\brief Header for counting semaphores for the avr thread library. + +\author R. Müller + +*/ + +/*! Structure of a semaphore data type + +The semaphore value is preset with 0. The event variable should be treated +as a opaque value. +*/ +typedef struct Sema_cs +{ + /*! the value; if <0, if is the number of waiting threads \n + if >0, it is the number of possible requests without blocking */ + volatile int value; + /*! the event, which will block the waiting threads */ + volatile avr_thread_event e; +} Sema_cs; + +void request_cs(struct Sema_cs * s); +void release_cs(struct Sema_cs * s); +