ChibiOS/RT
2.5.1
Counting Semaphores
Collaboration diagram for Counting Semaphores:

Detailed Description

Semaphores related APIs and services.

Operation mode

Semaphores are a flexible synchronization primitive, ChibiOS/RT implements semaphores in their "counting semaphores" variant as defined by Edsger Dijkstra plus several enhancements like:

The binary semaphores variant can be easily implemented using counting semaphores.
Operations defined for semaphores:

Semaphores can be used as guards for mutual exclusion zones (note that mutexes are recommended for this kind of use) but also have other uses, queues guards and counters for example.
Semaphores usually use a FIFO queuing strategy but it is possible to make them order threads by priority by enabling CH_USE_SEMAPHORES_PRIORITY in chconf.h.

Precondition:
In order to use the semaphore APIs the CH_USE_SEMAPHORES option must be enabled in chconf.h.

Data Structures

struct  Semaphore
 Semaphore structure. More...

Functions

void chSemInit (Semaphore *sp, cnt_t n)
 Initializes a semaphore with the specified counter value.
void chSemReset (Semaphore *sp, cnt_t n)
 Performs a reset operation on the semaphore.
void chSemResetI (Semaphore *sp, cnt_t n)
 Performs a reset operation on the semaphore.
msg_t chSemWait (Semaphore *sp)
 Performs a wait operation on a semaphore.
msg_t chSemWaitS (Semaphore *sp)
 Performs a wait operation on a semaphore.
msg_t chSemWaitTimeout (Semaphore *sp, systime_t time)
 Performs a wait operation on a semaphore with timeout specification.
msg_t chSemWaitTimeoutS (Semaphore *sp, systime_t time)
 Performs a wait operation on a semaphore with timeout specification.
void chSemSignal (Semaphore *sp)
 Performs a signal operation on a semaphore.
void chSemSignalI (Semaphore *sp)
 Performs a signal operation on a semaphore.
void chSemAddCounterI (Semaphore *sp, cnt_t n)
 Adds the specified value to the semaphore counter.
msg_t chSemSignalWait (Semaphore *sps, Semaphore *spw)
 Performs atomic signal and wait operations on two semaphores.

Macro Functions

#define chSemFastWaitI(sp)   ((sp)->s_cnt--)
 Decreases the semaphore counter.
#define chSemFastSignalI(sp)   ((sp)->s_cnt++)
 Increases the semaphore counter.
#define chSemGetCounterI(sp)   ((sp)->s_cnt)
 Returns the semaphore counter current value.

Defines

#define _SEMAPHORE_DATA(name, n)   {_THREADSQUEUE_DATA(name.s_queue), n}
 Data part of a static semaphore initializer.
#define SEMAPHORE_DECL(name, n)   Semaphore name = _SEMAPHORE_DATA(name, n)
 Static semaphore initializer.

Typedefs

typedef struct Semaphore Semaphore
 Semaphore structure.

Function Documentation

void chSemInit ( Semaphore sp,
cnt_t  n 
)

Initializes a semaphore with the specified counter value.

Parameters:
[out]sppointer to a Semaphore structure
[in]ninitial value of the semaphore counter. Must be non-negative.
Function Class:
Initializer, this function just initializes an object and can be invoked before the kernel is initialized.

Definition at line 79 of file chsem.c.

References chDbgCheck, queue_init, Semaphore::s_cnt, and Semaphore::s_queue.

Referenced by _heap_init(), chHeapInit(), and chMBInit().

void chSemReset ( Semaphore sp,
cnt_t  n 
)

Performs a reset operation on the semaphore.

Postcondition:
After invoking this function all the threads waiting on the semaphore, if any, are released and the semaphore counter is set to the specified, non negative, value.
Note:
The released threads can recognize they were waked up by a reset rather than a signal because the chSemWait() will return RDY_RESET instead of RDY_OK.
Parameters:
[in]sppointer to a Semaphore structure
[in]nthe new value of the semaphore counter. The value must be non-negative.
Function Class:
Normal API, this function can be invoked by regular system threads but not from within a lock zone.

Definition at line 102 of file chsem.c.

References chSchRescheduleS(), chSemResetI(), chSysLock, and chSysUnlock.

Here is the call graph for this function:

void chSemResetI ( Semaphore sp,
cnt_t  n 
)

Performs a reset operation on the semaphore.

Postcondition:
After invoking this function all the threads waiting on the semaphore, if any, are released and the semaphore counter is set to the specified, non negative, value.
This function does not reschedule so a call to a rescheduling function must be performed before unlocking the kernel. Note that interrupt handlers always reschedule on exit so an explicit reschedule must not be performed in ISRs.
Note:
The released threads can recognize they were waked up by a reset rather than a signal because the chSemWait() will return RDY_RESET instead of RDY_OK.
Parameters:
[in]sppointer to a Semaphore structure
[in]nthe new value of the semaphore counter. The value must be non-negative.
Function Class:
This is an I-Class API, this function can be invoked from within a system lock zone by both threads and interrupt handlers.

Definition at line 129 of file chsem.c.

References chDbgAssert, chDbgCheck, chDbgCheckClassI(), chSchReadyI(), isempty, lifo_remove(), notempty, RDY_RESET, Thread::rdymsg, Semaphore::s_cnt, and Semaphore::s_queue.

Referenced by chMBReset(), and chSemReset().

Here is the call graph for this function:

msg_t chSemWait ( Semaphore sp)

Performs a wait operation on a semaphore.

Parameters:
[in]sppointer to a Semaphore structure
Returns:
A message specifying how the invoking thread has been released from the semaphore.
Return values:
RDY_OKif the thread has not stopped on the semaphore or the semaphore has been signaled.
RDY_RESETif the semaphore has been reset using chSemReset().
Function Class:
Normal API, this function can be invoked by regular system threads but not from within a lock zone.

Definition at line 157 of file chsem.c.

References chSemWaitS(), chSysLock, and chSysUnlock.

Here is the call graph for this function:

msg_t chSemWaitS ( Semaphore sp)

Performs a wait operation on a semaphore.

Parameters:
[in]sppointer to a Semaphore structure
Returns:
A message specifying how the invoking thread has been released from the semaphore.
Return values:
RDY_OKif the thread has not stopped on the semaphore or the semaphore has been signaled.
RDY_RESETif the semaphore has been reset using chSemReset().
Function Class:
This is an S-Class API, this function can be invoked from within a system lock zone by threads only.

Definition at line 178 of file chsem.c.

References chDbgAssert, chDbgCheck, chDbgCheckClassS(), chSchGoSleepS(), currp, isempty, notempty, RDY_OK, Semaphore::s_cnt, Semaphore::s_queue, and THD_STATE_WTSEM.

Referenced by chSemWait().

Here is the call graph for this function:

msg_t chSemWaitTimeout ( Semaphore sp,
systime_t  time 
)

Performs a wait operation on a semaphore with timeout specification.

Parameters:
[in]sppointer to a Semaphore structure
[in]timethe number of ticks before the operation timeouts, the following special values are allowed:
  • TIME_IMMEDIATE immediate timeout.
  • TIME_INFINITE no timeout.
Returns:
A message specifying how the invoking thread has been released from the semaphore.
Return values:
RDY_OKif the thread has not stopped on the semaphore or the semaphore has been signaled.
RDY_RESETif the semaphore has been reset using chSemReset().
RDY_TIMEOUTif the semaphore has not been signaled or reset within the specified timeout.
Function Class:
Normal API, this function can be invoked by regular system threads but not from within a lock zone.

Definition at line 215 of file chsem.c.

References chSemWaitTimeoutS(), chSysLock, and chSysUnlock.

Here is the call graph for this function:

msg_t chSemWaitTimeoutS ( Semaphore sp,
systime_t  time 
)

Performs a wait operation on a semaphore with timeout specification.

Parameters:
[in]sppointer to a Semaphore structure
[in]timethe number of ticks before the operation timeouts, the following special values are allowed:
  • TIME_IMMEDIATE immediate timeout.
  • TIME_INFINITE no timeout.
Returns:
A message specifying how the invoking thread has been released from the semaphore.
Return values:
RDY_OKif the thread has not stopped on the semaphore or the semaphore has been signaled.
RDY_RESETif the semaphore has been reset using chSemReset().
RDY_TIMEOUTif the semaphore has not been signaled or reset within the specified timeout.
Function Class:
This is an S-Class API, this function can be invoked from within a system lock zone by threads only.

Definition at line 243 of file chsem.c.

References chDbgAssert, chDbgCheck, chDbgCheckClassS(), chSchGoSleepTimeoutS(), currp, isempty, notempty, RDY_OK, RDY_TIMEOUT, Semaphore::s_cnt, Semaphore::s_queue, THD_STATE_WTSEM, and TIME_IMMEDIATE.

Referenced by chMBFetchS(), chMBPostAheadS(), chMBPostS(), and chSemWaitTimeout().

Here is the call graph for this function:

void chSemSignal ( Semaphore sp)

Performs a signal operation on a semaphore.

Parameters:
[in]sppointer to a Semaphore structure
Function Class:
Normal API, this function can be invoked by regular system threads but not from within a lock zone.

Definition at line 271 of file chsem.c.

References chDbgAssert, chDbgCheck, chSchWakeupS(), chSysLock, chSysUnlock, fifo_remove(), isempty, notempty, RDY_OK, Semaphore::s_cnt, and Semaphore::s_queue.

Here is the call graph for this function:

void chSemSignalI ( Semaphore sp)

Performs a signal operation on a semaphore.

Postcondition:
This function does not reschedule so a call to a rescheduling function must be performed before unlocking the kernel. Note that interrupt handlers always reschedule on exit so an explicit reschedule must not be performed in ISRs.
Parameters:
[in]sppointer to a Semaphore structure
Function Class:
This is an I-Class API, this function can be invoked from within a system lock zone by both threads and interrupt handlers.

Definition at line 296 of file chsem.c.

References chDbgAssert, chDbgCheck, chDbgCheckClassI(), chSchReadyI(), fifo_remove(), isempty, notempty, RDY_OK, Thread::rdymsg, Semaphore::s_cnt, and Semaphore::s_queue.

Referenced by chMBFetchI(), chMBFetchS(), chMBPostAheadI(), chMBPostAheadS(), chMBPostI(), and chMBPostS().

Here is the call graph for this function:

void chSemAddCounterI ( Semaphore sp,
cnt_t  n 
)

Adds the specified value to the semaphore counter.

Postcondition:
This function does not reschedule so a call to a rescheduling function must be performed before unlocking the kernel. Note that interrupt handlers always reschedule on exit so an explicit reschedule must not be performed in ISRs.
Parameters:
[in]sppointer to a Semaphore structure
[in]nvalue to be added to the semaphore counter. The value must be positive.
Function Class:
This is an I-Class API, this function can be invoked from within a system lock zone by both threads and interrupt handlers.

Definition at line 327 of file chsem.c.

References chDbgAssert, chDbgCheck, chDbgCheckClassI(), chSchReadyI(), fifo_remove(), isempty, notempty, RDY_OK, Thread::rdymsg, Semaphore::s_cnt, and Semaphore::s_queue.

Here is the call graph for this function:

msg_t chSemSignalWait ( Semaphore sps,
Semaphore spw 
)

Performs atomic signal and wait operations on two semaphores.

Precondition:
The configuration option CH_USE_SEMSW must be enabled in order to use this function.
Parameters:
[in]spspointer to a Semaphore structure to be signaled
[in]spwpointer to a Semaphore structure to be wait on
Returns:
A message specifying how the invoking thread has been released from the semaphore.
Return values:
RDY_OKif the thread has not stopped on the semaphore or the semaphore has been signaled.
RDY_RESETif the semaphore has been reset using chSemReset().
Function Class:
Normal API, this function can be invoked by regular system threads but not from within a lock zone.

Definition at line 359 of file chsem.c.

References chDbgAssert, chDbgCheck, chSchGoSleepS(), chSchReadyI(), chSchRescheduleS(), chSysLock, chSysUnlock, currp, fifo_remove(), isempty, notempty, RDY_OK, Thread::rdymsg, Semaphore::s_cnt, Semaphore::s_queue, THD_STATE_WTSEM, and Thread::wtobjp.

Here is the call graph for this function:


Define Documentation

#define _SEMAPHORE_DATA (   name,
 
)    {_THREADSQUEUE_DATA(name.s_queue), n}

Data part of a static semaphore initializer.

This macro should be used when statically initializing a semaphore that is part of a bigger structure.

Parameters:
[in]namethe name of the semaphore variable
[in]nthe counter initial value, this value must be non-negative

Definition at line 72 of file chsem.h.

#define SEMAPHORE_DECL (   name,
 
)    Semaphore name = _SEMAPHORE_DATA(name, n)

Static semaphore initializer.

Statically initialized semaphores require no explicit initialization using chSemInit().

Parameters:
[in]namethe name of the semaphore variable
[in]nthe counter initial value, this value must be non-negative

Definition at line 83 of file chsem.h.

#define chSemFastWaitI (   sp)    ((sp)->s_cnt--)

Decreases the semaphore counter.

This macro can be used when the counter is known to be positive.

Function Class:
This is an I-Class API, this function can be invoked from within a system lock zone by both threads and interrupt handlers.

Definition at line 95 of file chsem.h.

Referenced by chMBFetchI(), chMBPostAheadI(), and chMBPostI().

#define chSemFastSignalI (   sp)    ((sp)->s_cnt++)

Increases the semaphore counter.

This macro can be used when the counter is known to be not negative.

Function Class:
This is an I-Class API, this function can be invoked from within a system lock zone by both threads and interrupt handlers.

Definition at line 104 of file chsem.h.

#define chSemGetCounterI (   sp)    ((sp)->s_cnt)

Returns the semaphore counter current value.

Function Class:
This is an I-Class API, this function can be invoked from within a system lock zone by both threads and interrupt handlers.

Definition at line 111 of file chsem.h.

Referenced by chMBFetchI(), chMBPostAheadI(), and chMBPostI().


Typedef Documentation

typedef struct Semaphore Semaphore

Semaphore structure.