Semaphore
https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/semaphore.h.html
Defines
-
SEM_FAILED ((sem_t *)0)
Semaphore initialization failed.
-
SEM_VALUE_MAX (0x7FFFFFFF)
Maximum value a semaphore may hold.
Typedefs
-
typedef void *sem_t
Functions
-
int sem_init(sem_t *semaphore, int pshared, unsigned count)
Initialize an unnamed semaphore with the given initial count.
Initializes the semaphore with an initial count of
count. When the MPU is enabled the semaphore state is protected from unprivileged threads. Thepsharedflag is accepted but ignored — semaphores are always process-private on this kernel.Error numbers:
EINVAL if
semaphoreis NULL orcountexceeds SEM_VALUE_MAX.ENOMEM if the kernel heap has insufficient memory for the semaphore.
See also
sem_post() for example.
- Parameters:
semaphore – Pointer to the semaphore.
pshared – Ignored; semaphores are always process-private.
count – Initial semaphore count, at most SEM_VALUE_MAX.
- Returns:
0 on success, -1 on error and errno set.
-
int sem_destroy(sem_t *semaphore)
Release the resources held by a semaphore.
The semaphore must have no waiters at the time of the call. The kernel object is freed back to the kernel heap and the caller’s handle is cleared, so any subsequent use of
semaphorefails with EINVAL.Error numbers:
- Parameters:
semaphore – Pointer to the semaphore.
- Returns:
int 0 on success, -1 on error and errno set.
-
int sem_post(sem_t *semaphore)
Increment a semaphore and wake one waiter, if any.
If the count is already at SEM_VALUE_MAX the call leaves the semaphore unchanged and reports an overflow. When QRT_CFG_DEFER_ENABLE is enabled the call may also be made from a deferred function or a timer callback (see qrt_defer_call()).
Error numbers:
EINVAL if the semaphore is invalid.
EOVERFLOW if the semaphore count is already at its maximum value.
- Parameters:
semaphore – Pointer to the semaphore.
- Returns:
int 0 on success, -1 on error and errno set.
static sem_t event_sem; static unsigned int events; static void event_deferred(qrt_u32_t parameter) { (void)parameter; (void)sem_post(&event_sem); } void Device_IRQHandler(void) { (void)qrt_defer_call(event_deferred, 0u); } void *worker(void *arg) { (void)arg; if (sem_init(&event_sem, 0, 0u) == 0) { for (;;) { (void)sem_wait(&event_sem); events++; } } return NULL; }
-
int sem_timedwait(sem_t *semaphore, const struct timespec *abstime)
Decrement a semaphore, waiting until
abstimeon CLOCK_REALTIME if it is currently zero.A thin wrapper around sem_clockwait() that fixes the clock to CLOCK_REALTIME.
Error numbers:
EINVAL if the semaphore is invalid.
EINVAL if the thread would have to wait and
abstimehas nanoseconds outside [0, 999’999’999].ETIMEDOUT if the thread would have to wait and the deadline has passed (negative seconds lie before the epoch), or elapses before the count becomes positive.
See also
sem_clockwait() for example.
- Parameters:
semaphore – Pointer to the semaphore.
abstime – Pointer to the absolute time to wait until.
- Returns:
0 on success, -1 on error and errno set.
-
int sem_clockwait(sem_t *semaphore, clockid_t clock_id, const struct timespec *abstime)
Decrement a semaphore, waiting until
abstimeon the chosen clock if it is currently zero.If the count is positive it is decremented and the call returns immediately. Otherwise the caller blocks on the semaphore’s wait list and is woken by sem_post() or when the deadline elapses. Every
abstime, {0, 0} included, is an absolute time onclock_id; one with negative seconds lies before the epoch and has already passed. The call must be made from a thread, never from a deferred function or a timer callback.Error numbers:
EINVAL if the semaphore is invalid.
EINVAL if the thread would have to wait and
clock_idis not a supported clock.EINVAL if the thread would have to wait and
abstimehas nanoseconds outside [0, 999’999’999].ETIMEDOUT if the thread would have to wait and the deadline has passed (negative seconds lie before the epoch), or elapses before the count becomes positive.
- Parameters:
semaphore – Pointer to the semaphore.
clock_id – Clock ID to use for the timeout.
abstime – Pointer to the absolute time to wait until.
- Returns:
0 on success, -1 on error and errno set.
static unsigned int events; static unsigned int timeouts; void *worker(void *arg) { sem_t *sem = (sem_t *)arg; struct timespec deadline; for (;;) { (void)clock_gettime(CLOCK_MONOTONIC, &deadline); deadline.tv_sec += 1; if (sem_clockwait(sem, CLOCK_MONOTONIC, &deadline) == 0) { events++; } else if (errno == ETIMEDOUT) { timeouts++; } } return NULL; }
-
int sem_trywait(sem_t *semaphore)
Decrement a semaphore if doing so will not block.
Never blocks: the call succeeds when the count is positive and reports EAGAIN otherwise. When QRT_CFG_DEFER_ENABLE is enabled the call may also be made from a deferred function or a timer callback (see qrt_defer_call()), which sem_wait(), sem_timedwait() and sem_clockwait() may not.
Error numbers:
- Parameters:
semaphore – Pointer to the semaphore.
- Returns:
0 on success, -1 on error and errno set.
-
int sem_wait(sem_t *semaphore)
Decrement a semaphore, waiting indefinitely if it is currently zero.
Equivalent to sem_timedwait() with a NULL deadline.
Error numbers:
EINVAL if the semaphore is invalid.
See also
sem_post() for example.
- Parameters:
semaphore – Pointer to the semaphore.
- Returns:
0 on success, -1 on error and errno set.
-
int sem_getvalue(sem_t *semaphore, int *sval)
Read a semaphore’s current count into
sval.Stores the current count, or 0 when the semaphore is locked (held with no remaining permits). When QRT_CFG_DEFER_ENABLE is enabled the call may also be made from a deferred function or a timer callback (see qrt_defer_call()).
Error numbers:
EINVAL if the semaphore is invalid.
- Parameters:
semaphore – Pointer to the semaphore.
sval – Pointer to the location where the current value will be stored.
- Returns:
int 0 on success, -1 on error and errno set.
-
sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value)
Not supported.
- Returns:
Always SEM_FAILED and sets errno to ENOSYS.