SYS/BIOS
7.00
|
Semaphore Manager.
The Semaphore manager makes available a set of functions that manipulate semaphore objects. Semaphores can be used for task synchronization and mutual exclusion.
Semaphores can be counting semaphores or binary semaphores. Counting semaphores keep track of the number of times the semaphore has been posted with Semaphore_post(). This is useful, for example, if you have a group of resources that are shared between tasks. Such tasks might call Semaphore_pend() to see if a resource is available before using one.
Binary semaphores can have only two states: available (count = 1) and unavailable (count = 0). They can be used to share a single resource between tasks. They can also be used for a basic signaling mechanism, where the semaphore can be posted multiple times. Binary semaphores do not keep track of the count; they simply track whether the semaphore has been posted or not.
See Semaphore_getCount() for more details of the 'count' behavior.
The Mailbox module uses a counting semaphore internally to manage the count of free (or full) mailbox elements. Another example of a counting semaphore is an ISR that might fill multiple buffers of data for consumption by a task. After filling each buffer, the ISR puts the buffer on a queue and calls Semaphore_post(). The task waiting for the data calls Semaphore_pend(), which simply decrements the semaphore count and returns or blocks if the count is 0. The semaphore count thus tracks the number of full buffers available for the task.
Semaphore_pend() is used to wait for a semaphore. The timeout parameter allows the task to wait until a timeout, wait indefinitely, or not wait at all. The return value is used to indicate if the semaphore was signaled successfully.
Semaphore_post() is used to signal a semaphore. If a task is waiting for the semaphore, Semaphore_post() removes the task from the semaphore queue and puts it on the ready queue. If no tasks are waiting, Semaphore_post() simply increments the semaphore count and returns. For a binary semaphore the count is always set to one.
To use the Semaphore module or to set any of the Semaphore module configuration variables, the following must be added to the app.syscfg file:
Function | Hwi | Swi | Task | Main | Startup |
---|---|---|---|---|---|
Semaphore_Params_init | Y | Y | Y | Y | Y |
Semaphore_construct | N | N | Y | Y | N |
Semaphore_create | N | N | Y | Y | N |
Semaphore_delete | N | N | Y | Y | N |
Semaphore_destruct | N | N | Y | Y | N |
Semaphore_getCount | Y | Y | Y | Y | Y |
Semaphore_pend | N* | N* | Y | N* | N |
Semaphore_post | Y | Y | Y | Y | N |
Semaphore_registerEvent | N | N | Y | Y | Y |
Semaphore_reset | N | N | Y | Y | N |
Definitions: (N* means OK to call iff the timeout
parameter is set to '0'.)
|
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <ti/sysbios/knl/Queue.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/knl/Clock.h>
#include <ti/sysbios/knl/Event.h>
#include <ti/sysbios/runtime/Error.h>
Go to the source code of this file.
Data Structures | |
struct | Semaphore_Params |
struct | Semaphore_Struct |
Macros | |
#define | Semaphore_A_badContext "bad calling context - must be called from a Task" |
Asserted when Semaphore_pend() is called with non-zero timeout from other than a Task context. More... | |
#define | Semaphore_A_noEvents "the Semaphore.supportsEvents flag is disabled" |
Asserted by Semaphore_create() if Semaphore.supportsEvents is false and an Event object is passed to Semaphore_create(). More... | |
#define | Semaphore_A_overflow "count has exceeded 65535 and rolled over" |
Asserted when Semaphore_post() has been called when the 16 bit semaphore count is at its maximum value of 65535. More... | |
#define | Semaphore_A_pendTaskDisabled "cannot call Semaphore_pend() while the Task or Swi scheduler is disabled" |
Assert raised if Semaphore_pend() is called with the Task or Swi scheduler disabled. More... | |
Typedefs | |
typedef struct Semaphore_Params | Semaphore_Params |
typedef struct Semaphore_Struct | Semaphore_Object |
typedef struct Semaphore_Struct | Semaphore_Struct |
typedef Semaphore_Struct * | Semaphore_Handle |
typedef Semaphore_Struct * | Semaphore_Instance |
typedef enum Semaphore_Mode | Semaphore_Mode |
Semaphore types. More... | |
Enumerations | |
enum | Semaphore_Mode { Semaphore_Mode_COUNTING = 0x0, Semaphore_Mode_BINARY = 0x1, Semaphore_Mode_COUNTING_PRIORITY = 0x2, Semaphore_Mode_BINARY_PRIORITY = 0x3 } |
Semaphore types. More... | |
Functions | |
Semaphore_Handle | Semaphore_create (int count, const Semaphore_Params *prms, Error_Block *eb) |
Create a Semaphore object. More... | |
Semaphore_Handle | Semaphore_construct (Semaphore_Struct *obj, int count, const Semaphore_Params *prms) |
Construct a semaphore. More... | |
void | Semaphore_delete (Semaphore_Handle *semaphore) |
Delete a semaphore. More... | |
void | Semaphore_destruct (Semaphore_Struct *obj) |
Destruct a semaphore. More... | |
void | Semaphore_Params_init (Semaphore_Params *prms) |
Initialize the Semaphore_Params structure with default values. More... | |
Semaphore_Handle | Semaphore_Object_first (void) |
return handle of the first Semaphore on Semaphore list More... | |
Semaphore_Handle | Semaphore_Object_next (Semaphore_Handle semaphore) |
return handle of the next Semaphore on Semaphore list More... | |
int | Semaphore_getCount (Semaphore_Handle semaphore) |
Get current semaphore count. More... | |
bool | Semaphore_pend (Semaphore_Handle semaphore, uint32_t timeout) |
Wait for a semaphore. More... | |
void | Semaphore_post (Semaphore_Handle semaphore) |
Signal a semaphore. More... | |
void | Semaphore_registerEvent (Semaphore_Handle semaphore, Event_Handle event, unsigned int eventId) |
Register an Event Object with a semaphore. More... | |
void | Semaphore_reset (Semaphore_Handle semaphore, int count) |
Reset semaphore count. More... | |
Variables | |
const bool | Semaphore_supportsEvents |
Support Semaphores with Events? More... | |
const bool | Semaphore_supportsPriority |
Support Task priority pend queuing? More... | |
#define Semaphore_A_badContext "bad calling context - must be called from a Task" |
Asserted when Semaphore_pend() is called with non-zero timeout from other than a Task context.
#define Semaphore_A_noEvents "the Semaphore.supportsEvents flag is disabled" |
Asserted by Semaphore_create() if Semaphore.supportsEvents is false and an Event object is passed to Semaphore_create().
#define Semaphore_A_overflow "count has exceeded 65535 and rolled over" |
Asserted when Semaphore_post() has been called when the 16 bit semaphore count is at its maximum value of 65535.
#define Semaphore_A_pendTaskDisabled "cannot call Semaphore_pend() while the Task or Swi scheduler is disabled" |
Assert raised if Semaphore_pend() is called with the Task or Swi scheduler disabled.
typedef struct Semaphore_Params Semaphore_Params |
typedef struct Semaphore_Struct Semaphore_Object |
typedef struct Semaphore_Struct Semaphore_Struct |
typedef Semaphore_Struct* Semaphore_Handle |
typedef Semaphore_Struct* Semaphore_Instance |
typedef enum Semaphore_Mode Semaphore_Mode |
Semaphore types.
These enumerations specify the type of semaphore.
Tasks wait for the semaphore in FIFO order unless the PRIORITY option is chosen.
For PRIORITY semaphores, the pending task will be inserted in the waiting list before the first task that has lower priority. This ensures that tasks of equal priority will pend in FIFO order.
enum Semaphore_Mode |
Semaphore types.
These enumerations specify the type of semaphore.
Tasks wait for the semaphore in FIFO order unless the PRIORITY option is chosen.
For PRIORITY semaphores, the pending task will be inserted in the waiting list before the first task that has lower priority. This ensures that tasks of equal priority will pend in FIFO order.
Enumerator | |
---|---|
Semaphore_Mode_COUNTING | Counting (FIFO) |
Semaphore_Mode_BINARY | Binary (FIFO) |
Semaphore_Mode_COUNTING_PRIORITY | Counting (priority-based) |
Semaphore_Mode_BINARY_PRIORITY | Binary (priority-based) |
Semaphore_Handle Semaphore_create | ( | int | count, |
const Semaphore_Params * | prms, | ||
Error_Block * | eb | ||
) |
Create a Semaphore object.
This function creates a new Semaphore object which is initialized to count.
count | initial semaphore count |
prms | Semaphore parameters |
eb | error block |
Semaphore | handle (NULL on failure) |
Semaphore_Handle Semaphore_construct | ( | Semaphore_Struct * | obj, |
int | count, | ||
const Semaphore_Params * | prms | ||
) |
Construct a semaphore.
Semaphore_construct is equivalent to Semaphore_create except that the Semaphore_Struct is pre-allocated. See Semaphore_create() for a description of this API.
obj | pointer to a Semaphore object |
count | initial semaphore count |
prms | Semaphore parameters |
Semaphore | handle (NULL on failure) |
void Semaphore_delete | ( | Semaphore_Handle * | semaphore | ) |
Delete a semaphore.
Semaphore_delete deletes a Semaphore object. Note that Semaphore_delete takes a pointer to a Semaphore_Handle which enables Semaphore_delete to set the Semaphore_handle to NULL.
semaphore | pointer to Semaphore handle |
void Semaphore_destruct | ( | Semaphore_Struct * | obj | ) |
Destruct a semaphore.
Semaphore_destruct destructs a Semaphore object.
obj | pointer to Semaphore object |
void Semaphore_Params_init | ( | Semaphore_Params * | prms | ) |
Initialize the Semaphore_Params structure with default values.
Semaphore_Params_init initializes the Semaphore_Params structure with default values. Semaphore_Params_init should always be called before setting individual parameter fields. This allows new fields to be added in the future with compatible defaults – existing source code does not need to change when new fields are added.
prms | pointer to uninitialized params structure |
Semaphore_Handle Semaphore_Object_first | ( | void | ) |
return handle of the first Semaphore on Semaphore list
Return the handle of the first Semaphore on the create/construct list. NULL if no Semaphore have been created or constructed.
Semaphore | handle |
Semaphore_Handle Semaphore_Object_next | ( | Semaphore_Handle | semaphore | ) |
return handle of the next Semaphore on Semaphore list
Return the handle of the next Semaphore on the create/construct list. NULL if no more Semaphore are on the list.
semaphore | Semaphore handle |
Semaphore | handle |
int Semaphore_getCount | ( | Semaphore_Handle | semaphore | ) |
Get current semaphore count.
This function returns the current value of the semaphore specified by the handle.
A semaphore's count is incremented when Semaphore_post() is called. If configured as a binary semaphore, the count will not increment past 1. If configured as a counting semaphore, the count will continue incrementing and will rollover to zero after reaching a count of 65,535. Care must be taken in applications to avoid the rollover situation as a count of zero will always be interpreted as an empty semaphore.
A semaphore's count is decremented, if non-zero, when Semaphore_pend() is called. A task will block on a semaphore if the count is zero when Semaphore_pend() is called. An empty semaphore will always have a count of zero regardless of the number of tasks that are blocked on it.
semaphore | Semaphore handle |
current | semaphore count |
bool Semaphore_pend | ( | Semaphore_Handle | semaphore, |
uint32_t | timeout | ||
) |
Wait for a semaphore.
If the semaphore count is greater than zero (available), this function decrements the count and returns true. If the semaphore count is zero (unavailable), this function suspends execution of the current task (leaving the count equal to zero) until post() is called or the timeout expires.
A timeout value of BIOS_WAIT_FOREVER causes the task to wait indefinitely for its semaphore to be posted.
A timeout value of BIOS_NO_WAIT causes Semaphore_pend to return immediately.
If the Semaphore object has been configured with an embedded Event object, then prior to returning from this function, the Event object's state is updated to reflect the new value of 'count'. If 'count' is zero, then the configured Event_Id is cleared in the Event object. If 'count' is non-zero, then the configured Event_Id is set in the Event object.
semaphore | Semaphore handle |
timeout | return after this many system time units |
true | if successful, false if timeout |
void Semaphore_post | ( | Semaphore_Handle | semaphore | ) |
Signal a semaphore.
If any tasks are waiting on the semaphore, this function readies the first task waiting for the semaphore without incrementing the count. If no task is waiting, this function simply increments the semaphore count and returns. In the case of a binary semaphore, the count has a maximum value of one.
semaphore | Semaphore handle |
void Semaphore_registerEvent | ( | Semaphore_Handle | semaphore, |
Event_Handle | event, | ||
unsigned int | eventId | ||
) |
Register an Event Object with a semaphore.
Ordinarily, an Event object and eventId are configured at Semaphore create time.
This API is provided so that Semaphore-using middleware can support implicit Event posting without having to be retrofitted.
After the Event object and eventId are registered with the Semaphore:
Event_post(event, eventId) will be invoked when Semaphore_post(sem) is called.
Event_pend(event, eventId, 0, timeout) will be invoked when Semaphore_pend(sem, timeout) is called.
semaphore | Semaphore handle |
event | void * to Event Object |
eventId | Event ID |
void Semaphore_reset | ( | Semaphore_Handle | semaphore, |
int | count | ||
) |
Reset semaphore count.
Resets the semaphore count to count. No task switch occurs when calling SEM_reset.
No tasks should be waiting on the semaphore when Semaphore_reset is called.
Semaphore_reset cannot be called by a Hwi or a Swi.
semaphore | Semaphore handle |
count | semaphore count |
const bool Semaphore_supportsEvents |
Support Semaphores with Events?
The default for this parameter is false.
This parameter is set in the app.syscfg file:
const bool Semaphore_supportsPriority |
Support Task priority pend queuing?
The default for this parameter is true.
This parameter is set in the app.syscfg file: