EtcPal
HEAD (unstable)
ETC Platform Abstraction Layer (EtcPal)
|
View other versions:
|
Counting semaphore objects.
A counting semaphore is a synchronization value which can never fall below zero. Each time the semaphore is posted, its count increases. Each time the semaphore is taken, its count decreases, unless the count is zero, in which case the task waiting for it is blocked until it is posted again. This is often used for tracking events that can occur multiple times before being serviced or pools of resources.
Usage example:
etcpal_sem implementations use different constructs under the hood on various platforms. Also, different platforms affect the behavior of certain functions.
Platform | ETCPAL_SEM_HAS_TIMED_WAIT | ETCPAL_SEM_HAS_POST_FROM_ISR | ETCPAL_SEM_HAS_MAX_COUNT | ETCPAL_SEM_MUST_BE_BALANCED | Underlying Type |
---|---|---|---|---|---|
FreeRTOS | Yes | Yes | Yes | No | Counting Semaphores |
Linux | Yes | No | No | No | POSIX Semaphores |
macOS | No | No | No | Yes | Dispatch Semaphores |
MQX | Yes | No | No | No | Lightweight Semaphores |
Windows | Yes | No | Yes | No | Semaphore objects |
Zephyr | Yes | Yes | Yes | No | Semaphores |
Macros | |
#define | ETCPAL_SEM_HAS_TIMED_WAIT /* platform-defined */ |
Whether etcpal_sem_timed_wait() is meaningful on this platform. More... | |
#define | ETCPAL_SEM_HAS_POST_FROM_ISR /* platform-defined */ |
Whether etcpal_sem_post_from_isr() is meaningful on this platform. More... | |
#define | ETCPAL_SEM_HAS_MAX_COUNT /* platform-defined */ |
Whether counting semaphores have a maximum count on this platform. More... | |
#define | ETCPAL_SEM_MUST_BE_BALANCED /* platform-defined */ |
Whether the semaphore must have its initial count before being destroyed. More... | |
Typedefs | |
typedef PLATFORM_DEFINED | etcpal_sem_t |
The semaphore identifier. More... | |
Functions | |
bool | etcpal_sem_create (etcpal_sem_t *id, unsigned int initial_count, unsigned int max_count) |
Create a new counting semaphore. More... | |
bool | etcpal_sem_wait (etcpal_sem_t *id) |
Wait for a semaphore. More... | |
bool | etcpal_sem_try_wait (etcpal_sem_t *id) |
Try to wait for a semaphore. More... | |
bool | etcpal_sem_timed_wait (etcpal_sem_t *id, int timeout_ms) |
Wait for a semaphore, giving up after a timeout. More... | |
bool | etcpal_sem_post (etcpal_sem_t *id) |
Post a semaphore. More... | |
bool | etcpal_sem_post_from_isr (etcpal_sem_t *id) |
Post a semaphore from an interrupt context. More... | |
void | etcpal_sem_destroy (etcpal_sem_t *id) |
Destroy a semaphore object. More... | |
#define ETCPAL_SEM_HAS_MAX_COUNT /* platform-defined */ |
Whether counting semaphores have a maximum count on this platform.
Some platforms have a maximum count after which a counting semaphore can no longer be posted. If defined to 0, the max_count argument to etcpal_sem_create() is ignored.
#define ETCPAL_SEM_HAS_POST_FROM_ISR /* platform-defined */ |
Whether etcpal_sem_post_from_isr() is meaningful on this platform.
Some platforms have a different method for posting a signal from an interrupt context. If defined to 0, etcpal_sem_post_from_isr() executes the equivalent of etcpal_sem_post().
#define ETCPAL_SEM_HAS_TIMED_WAIT /* platform-defined */ |
Whether etcpal_sem_timed_wait() is meaningful on this platform.
If defined to 0, etcpal_sem_timed_wait() executes the equivalent of etcpal_sem_try_wait() if given a timeout of 0, or etcpal_sem_wait() otherwise.
#define ETCPAL_SEM_MUST_BE_BALANCED /* platform-defined */ |
Whether the semaphore must have its initial count before being destroyed.
Currently the only platform for which this is true is macOS. Calls to etcpal_sem_wait() and friends must be balanced with calls to etcpal_sem_post() and friends. If the semaphore does not have its initial count when being destroyed, an EXC_BAD_INSTRUCTION exception is raised.
typedef PLATFORM_DEFINED etcpal_sem_t |
The semaphore identifier.
Depending on the platform, this could be a scalar type or a struct.
bool etcpal_sem_create | ( | etcpal_sem_t * | id, |
unsigned int | initial_count, | ||
unsigned int | max_count | ||
) |
Create a new counting semaphore.
If initial_count is 0, calls to etcpal_sem_wait() will block until the first call is made to etcpal_sem_post().
[out] | id | Semaphore identifier on which to create a semaphore. If this function returns true, *id becomes valid for calls to other etcpal_sem API functions. |
[in] | initial_count | The count value assigned to the semaphore when it is created. |
[in] | max_count | The maximum count that the semaphore can have. This is not meaningful on all platforms - see ETCPAL_SEM_HAS_MAX_COUNT. If it is meaningful, once the count reaches this value, the semaphore can no longer be posted. |
void etcpal_sem_destroy | ( | etcpal_sem_t * | id | ) |
Destroy a semaphore object.
NOTE: if ETCPAL_SEM_MUST_BE_BALANCED is defined to 1, the semaphore must have its initial count before being destroyed.
[in] | id | Identifier for the semaphore to destroy. |
bool etcpal_sem_post | ( | etcpal_sem_t * | id | ) |
Post a semaphore.
If the count is zero and there is a thread waiting for the semaphore, wakes up the thread without incrementing the count. Otherwise, increments the count, unless the count is equal to the value provided for max_count when the semaphore was created, in which case it returns false. (note: the max_count behavior does not occur on all platforms. See the table in the module overview for more information).
[in] | id | Identifier for the semaphore to post. |
bool etcpal_sem_post_from_isr | ( | etcpal_sem_t * | id | ) |
Post a semaphore from an interrupt context.
This function is only meaningful on some platforms; namely, those which have a different method for posting a semaphore from an interrupt context. The value of ETCPAL_SEM_HAS_POST_FROM_ISR can be used to determine whether this function is meaningful on the current platform. If it is defined to 0, this function simply executes the equivalent of etcpal_sem_post().
[in] | id | Identifier for the semaphore to post. |
bool etcpal_sem_timed_wait | ( | etcpal_sem_t * | id, |
int | timeout_ms | ||
) |
Wait for a semaphore, giving up after a timeout.
If the semaphore's count is nonzero, decrements the count and returns true. Otherwise, waits up to timeout_ms for the semaphore to be posted, returning false if this timeout expires.
This function is not honored on all platforms. The value of ETCPAL_SEM_HAS_TIMED_WAIT can be used to determine whether this function is honored on the current platform. If it is defined to 0, this function executes the equivalent of etcpal_sem_try_wait() if timeout_ms is 0, or etcpal_sem_wait() otherwise.
[in] | id | Identifier for the semaphore for which to wait. |
[in] | timeout_ms | Maximum amount of time to wait for the semaphore, in milliseconds. If ETCPAL_WAIT_FOREVER is given, the result is the same as if etcpal_sem_wait() was called. |
bool etcpal_sem_try_wait | ( | etcpal_sem_t * | id | ) |
Try to wait for a semaphore.
If the semaphore's count is nonzero, decrements the count and returns true. Otherwise, returns false immediately.
[in] | id | Identifier for the semaphore for which to attempt to wait. |
bool etcpal_sem_wait | ( | etcpal_sem_t * | id | ) |
Wait for a semaphore.
If the semaphore's count is nonzero, decrements the count and returns true. Otherwise, blocks until a call to etcpal_sem_post() on the semaphore.
[in] | id | Identifier for the semaphore for which to wait. |