Semaphore

https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/semaphore.h.html

Copyright

Copyright (c) 2025 TNX Software Ltd. All rights reserved. Licensed under the terms of the QuantumRT Kernel License. See the LICENSE file in the root of this package for details.

Defines

SEM_FAILED ((sem_t *)0)

Semaphore initialization failed.

Functions

int sem_init(sem_t *semaphore, int pshared, unsigned count)

Initialize a semaphore.

Error numbers:

Parameters:
  • semaphore – Pointer to the semaphore.

Returns:

0 on success, -1 on error and errno set.

int sem_destroy(sem_t *semaphore)

Destroy the semaphore. Destroying a semaphore that has threads waiting on it results in undefined behavior.

Error numbers:

  • EINVAL if the semaphore is invalid.

Parameters:
  • semaphore – Pointer to the semaphore.

Returns:

int 0 on success, -1 on error and errno set.

int sem_post(sem_t *semaphore)

Unlock a semaphore, incrementing its count and potentially waking a waiting thread.

Error numbers:

  • EINVAL if the semaphore is invalid.

Parameters:
  • semaphore – Pointer to the semaphore.

Returns:

int 0 on success, -1 on error and errno set.

// Example:  PID Control Loop with ADC Feedback

#include "qrt.h"
#include "semaphore.h"

sem_t adc_sem;

void ADC_DeferredHandler(qrt_u32_t arg)
{
    sem_post((sem_t *)arg);     // Signal new sample ready
}

void ADC_IRQHandler(void)
{
    // Kernel calls not allowed in ISR context
    qrt_defer_call(ADC_DeferredHandler, (qrt_u32_t)&adc_sem);
}

void *control_loop(void *)
{
    sem_init(&adc_sem, 0, 0u);

    adc_init();

    for (;;)
    {
        sem_wait(&adc_sem);      // Wait for ADC sample ready
        update_pid_controller();
    }
}

int sem_timedwait(sem_t *semaphore, const struct timespec *abstime)

Try to lock a semaphore with timed blocking.

Error numbers:

  • EINVAL if the thread would have wait, and the abstime is invalid (less than 0 or greater than 1000 million).

  • ETIMEDOUT if the wait timed out.

  • EDEADLK if a deadlock condition is detected.

  • 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_clockwait(sem_t *semaphore, clockid_t clock_id, const struct timespec *abstime)

Try to lock a semaphore with blocking and a specific clock.

Error numbers:

  • EINVAL if the thread would have wait, and the abstime is invalid (less than 0 or greater than 1000 million).

  • ETIMEDOUT if the wait timed out.

  • EDEADLK if a deadlock condition is detected.

  • EINVAL if the semaphore is invalid.

  • EINVAL if the clock_id is other than CLOCK_MONOTONIC.

  • EOVERFLOW if the seconds value in abstime is too large to be represented as ticks.

Parameters:
  • semaphore – Pointer to the semaphore.

Returns:

0 on success, -1 on error and errno set.

int sem_trywait(sem_t *semaphore)

Try to lock a semaphore without blocking.

Error numbers:

  • EAGAIN if the semaphore is already held.

  • EINVAL if the semaphore is invalid

Parameters:
  • semaphore – Pointer to the semaphore.

Returns:

0 on success, -1 on error and errno set.

int sem_wait(sem_t *semaphore)

Try to lock a semaphore with blocking.

Error numbers:

Parameters:
  • semaphore – Pointer to the semaphore.

Returns:

0 on success, -1 on error and errno set.

int sem_getvalue(sem_t *semaphore, int *sval)

Get the current value of the semaphore.

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 -1 and sets errno to ENOSYS.

int sem_close(sem_t *semaphore)

Not supported.

Returns:

Always -1 and sets errno to ENOSYS.

Not supported.

Returns:

Always -1 and sets errno to ENOSYS.

struct sem_t