Counting semaphores


Detailed Description

Counting semaphores can be used to keep a shared count by different tasks.

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)


Function Documentation

void csem_init ( csem_t cs,
csemval_t  init_val,
csemval_t  max_val 
)

Initialize counting semaphore.

Calling Context:

  1. Before os_start().
  2. From within a task.
  3. From an ISR.

Parameters:
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.

csemval_t csem_count ( csem_t cs  ) 

Obtain the value of a counting semaphore.

Calling Context:

  1. Before os_start().
  2. From within a task.
  3. From an ISR.

NOTE: the counting semaphore must previously have been initialized for this to have any meaningful return value.

Parameters:
cs Pointer to counting semaphore
Returns:
The value of the semaaphore

csemval_t csem_P ( csem_t cs,
const trtime_t timeout,
uint8_t  options 
)

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 (

See also:
os_task_resume) this task. The caller can prevent blocking by using the O_NONBLOCKING option. On success, the value returned is the value of the semaphore immediately after the decrease.
Calling Context:
  1. From within a task.
  2. From an ISR (error if blocking needed).

Parameters:
cs Pointer to counting semaphore
timeout Timeout. This can be 0, for infinite timeout.
options [O_RELATIVE_TIME | O_NONBLOCKING]
Returns:
{Semaphore count if successful, ERR_WOULDBLOCK_ISR, ERR_WOULDBLOCK_MUTEX, ERR_TIMEOUT, ERR_RESUMED }

csemval_t csem_V ( csem_t cs  ) 

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:

  1. From within a task.
  2. From an ISR.

Parameters:
cs Pointer to counting semaphore
Returns:
{Semaphore count or ERR_FULL}


TiROS User Manual: Last Updated on Fri Jul 20 10:52:24 2007