They have a value between 0 to a specified MAX value.
The P() operation (Prolaag) decreases the count of the counting semaphore. If the count is zero, the task blocks since it cannot be decreased further. The V() operation (Verhoog) increments the count of the counting semaphore. This operation is non-blocking.
Counting semaphores are useful for event notifications. For example, a message server task can perform a P() operation on a message counting semaphore. When a message has to be sent to the message server, a message client task performs a V() operation on the same semaphore. This unblocks the message server. If multiple client tasks send messages, the message server has a count of the number of times the message counter has been V()ed.
If multiple servers are blocked on a counting semaphore, the highest priority blocked server is alerted when the semaphore is incremented.
NOTE: A custom type csemval_t is used for the semaphore count. This is of type signed integer. By default, it is an 8-bit integer (max val of 127). This can be overridden (see tr_types.h).
NOTE: Always initialize before use.
csem_t cs; // Previously initialized (possibly in main) void task1(void *dummy) { while(1) { csem_P(&cs, 0, 0); // Wait for semaphore do_stuff(); } } void task2(void *dummy) { while(1) { do_stuff(); do_other_stuff(); // Release task1 csem_V(&cs); // Release semaphore do_stuff(); } }
Functions | |
void | csem_init (csem_t *cs, csemval_t init_val, csemval_t max_val) |
csemval_t | csem_count (csem_t *cs) |
csemval_t | csem_P (csem_t *cs, const trtime_t *timeout, uint8_t options) |
csemval_t | csem_V (csem_t *cs) |
Initialize counting semaphore.
Calling Context:
cs | Pointer to counting semaphore | |
init_val | Initial value | |
max_val | Maximum value for the counting semaphore. The semaphore cannot be incremented past this number. |
Obtain the value of a counting semaphore.
Calling Context:
NOTE: the counting semaphore must previously have been initialized for this to have any meaningful return value.
cs | Pointer to counting semaphore |
Decrease (prolaag) the value of a counting semaphore.
This decreases the value of a counting semaphore. If the value is zero, the caller blocks until another task increments the semaphore OR until the timeout duration OR until another task explicitly resumes (
cs | Pointer to counting semaphore | |
timeout | Timeout. This can be 0, for infinite timeout. | |
options | [O_RELATIVE_TIME | O_NONBLOCKING] |
Increase (verhoog) the value of a counting semaphore.
This is a non-blocking function. If the maximum value of the semaphore is reached, an ERR_FULL message is returned.
NOTE: On success, the value returned is the value of the semaphore immediately after the increase. If there are other tasks waiting to csem_P on the counting semaphore, the value returned is that before these other tasks have completed the csem_P operation. Example:
csemval_t tmp; // Current state of counting semaphore cs is 0. There are two // tasks blocked doing a csem_P on it. tmp = csem_V(&cs); // Value of tmp is 1, because of the csem_V tmp = csem_count(&cs); // Value of tmp is 0, because one of the tasks that // that was blocked on csem_P(&cs) has // completed the prolaag and now the value // of cs is back to zero.
Calling Context:
cs | Pointer to counting semaphore |