OCEOS/oceos inter-task communication/semaphore
Semaphore
Semaphore Introduction
A counting semaphore has an integer value that is always greater than or equal to zero. This value is set initially when the semaphore is created and is modified by atomic wait and signal operations.
Each counting semaphore has a pending jobs queue of jobs waiting for the semaphore value to become greater than zero.
Unlike a mutex, which must become available after a finite number of cycles, a counting semaphore may remain unavailable, i.e. at value zero, indefinitely unless a timeout has been specified.
When a wait operation is performed the semaphore value is decremented unless the semaphore is already zero and an appropriate status code returned.
Unlike many other OS, the job that performs the wait operation does not block if the semaphore value is zero. Instead OCEOS provides three options for the wait operation:
- In the oceos_sem_wait_continue() option if the semaphore value is 0 it remains unchanged and an appropriate status code is returned, the job continues taking this returned value into account.
- In the oceos_sem_wait_restart() or oceos_sem_wait_restart_timeout() option if the semaphore is zero the job terminates and restarts from its beginning when the semaphore is signaled or the timeout occurs.
- A job that was restarted as a result of a timeout does not terminate if it comes to oceos_sem_wait_restart_timeout() and the semaphore is still zero, an appropriate status is returned and the job continues taking this into account.
When the semaphore is signaled, its value is incremented, and any jobs on its pending jobs queue are transferred to the ready queue and also removed from the timed jobs queue if present.
The pending jobs queue order of jobs with the same priority is preserved in this transfer. The scheduler is then activated and may pre-empt the current executing job.
Note
If timeouts are used with semaphores the hardware specific timer initialization and handling must be set up by the developer please see here.
Semaphore Configuration
User must define NUMBER_OF_SEMAPHORES. If NUMBER_OF_SEMAPHORES is zero, semaphores are not used. The example can be found in OCEOS demo projects.
User must create defined number of semaphores before calling oceos_init_finish()#define NUMBER_OF_SEMAPHORES 2 /* * Create the application configuration structure */ struct application_configuration app_config = {0}; app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;
API Functions
Directive | Description | main | task | IRQ handler |
---|---|---|---|---|
oceos_sem_create() | Create semaphore | * | ||
oceos_sem_signal() | Signals a semaphore | * | * | |
oceos_sem_wait_continue() | Wait on semaphore | * | ||
oceos_sem_wait_restart() | Wait on semaphore | * | ||
oceos_sem_wait_restart_timeout() | Wait on semaphore | * | ||
oceos_sem_get_value() | Returns number of available permits | * | * | |
oceos_sem_penq_get_size() | Returns number of jobs on semaphore pending queue | * | * | |
oceos_sem_reset() | Restore permits to original value and frees tasks on pending queue | * | * |
oceos_sem_create()
Header File
semaphore.h
Description
Create a counting semaphore. If use_timeout = TRUE, timed actions must be initialized, please see herePrototype
enum DIRECTIVE_STATUS oceos_sem_create( sem_t sem_id, // counting semaphore ID (0 to 62) U16_t max_permits, // max number of permits (1 to 4094) U16_t count_permits, // initial number of permits (1 to 4094) U16_t pending_q_size, // max number of pending queue jobs (1 to 255) BOOLE_t use_timeout // whether timeout is used );Parameters
Parameter Description sem_id Counting semaphore ID (0 to 62) max_permits Max number of permits (1 to 4094) count_permits Initial number of permits (1 to 4094) pending_q_size Max number of pending queue jobs (1 to 254) use_timeout Specify if timeout are required, so oceos_sem_wait_restart_timeout() can be used Returns
This function returns enum DIRECTIVE_STATUS.
enum DIRECTIVE_STATUS Description NOT_CONFIGURED System Meta pointer is NULL or corrupt INCORRECT_STATE Init Meta pointer is NULL INVALID_ID Semaphore id is not OK INVALID_NUMBER max_permits or count_permits or pending_q_size is not OK TOO_MANY max_permits > count_permits INVALID_SIZE pending_q_size is zero SUCCESSFUL OK Example Usage
enum SEM_NAME{ s_tesla, s_audi }; enum DIRECTIVE_STATUS status; status = oceos_sem_create(s_tesla, 5, 5, 127, FALSE); if(SUCCESSFUL != status) { // Handle ERROR }
oceos_sem_signal()
Header File
semaphore.h
Description
Signals a semaphore, increments number of permits, transfers pending jobs to ready queue and also removes jobs from the timed jobs queue if timeout is used.Prototype
enum DIRECTIVE_STATUS oceos_sem_signal( sem_t sem_id // counting semaphore ID );Parameters
Parameter Description sem_id Counting semaphore ID Returns
This function returns enum DIRECTIVE_STATUS.
enum DIRECTIVE_STATUS Description NOT_CONFIGURED System Meta pointer is NULL or corrupt INCORRECT_STATE Init Meta pointer set in init state or scheduling not started INTERNAL_ERROR Semaphore fixed data pointer is NULL or (check log for more information) INVALID_ID Semaphore id is not OK TOO_MANY Semaphore max_permits value reached or (check log for more information) SUCCESSFUL All OK Example Usage
enum SEM_NAME{ s_tesla, s_audi }; enum DIRECTIVE_STATUS status; status = oceos_sem_signal(s_tesla); if(SUCCESSFUL != status) { // Handle ERROR }
oceos_sem_wait_continue()
Header File
semaphore.h
Description
Wait on semaphore, decrement the number of available permits for semaphore, if no permits, continue and task should handle unsuccessful result
Prototype
enum DIRECTIVE_STATUS oceos_sem_wait_continue( sem_t sem_id // counting semaphore ID );Parameters
Parameter Description sem_id Counting Semaphore ID Returns
This function returns enum DIRECTIVE_STATUS.
enum DIRECTIVE_STATUS Description NOT_CONFIGURED System Meta pointer is NULL or corrupt INCORRECT_STATE Init Meta pointer set in init state or scheduling not started INTERNAL_ERROR Semaphore fixed data pointer is NULL or (check log for more information) INVALID_ID Semaphore id is not OK UNSATISFIED Semaphore has no permits SUCCESSFUL All OK Example Usage
enum SEM_NAME{ s_tesla, s_audi }; enum DIRECTIVE_STATUS status; status = oceos_sem_wait_continue(s_tesla); if(SUCCESSFUL != status) { // Handle ERROR }
oceos_sem_wait_restart()
Header File
semaphore.h
Description
Wait on semaphore, if fail, put the job on pending queue and exit task. Job restarted will lose any data stored in variables on the stack, so it may be necessary for the application to store such data elsewhere, so that it is available when the job is restarted.Prototype
enum DIRECTIVE_STATUS oceos_sem_wait_restart( sem_t sem_id // counting semaphore ID );Parameters
Parameter Description sem_id Counting Semaphore ID Returns
This function returns enum DIRECTIVE_STATUS.
enum DIRECTIVE_STATUS Description NOT_CONFIGURED System Meta pointer is NULL or corrupt INCORRECT_STATE Init Meta pointer set in init state or scheduling not started INTERNAL_ERROR Semaphore fixed data pointer is NULL or (check log for more information) INVALID_ID Semaphore id is not OK UNSATISFIED Job was started as a result of a timeout on this semaphore TOO_MANY Semaphore pending queue is full SUCCESSFUL All OK Example Usage
enum SEM_NAME{ s_tesla, s_audi }; enum DIRECTIVE_STATUS status; status = oceos_sem_wait_restart(s_tesla); if(SUCCESSFUL != status) { // Handle ERROR }
oceos_sem_wait_restart_timeout()
Header File
semaphore.h
Description
Wait on semaphore, if fail, put job on pending queue with optional timeout.Note
In order to use timeouts, timed actions must be configured, please see here and semaphore must be created with flag use_timeout is set to TRUE.
Prototype
enum DIRECTIVE_STATUS oceos_sem_wait_restart_timeout( sem_t sem_id, // counting semaphore ID U64_t timeout // timeout, restart time if no signal, 0 => ignore );Parameters
Parameter Description sem_id Counting Semaphore ID timeout Restart time if no signal, 0 => ignore Returns
This function returns enum DIRECTIVE_STATUS.
enum DIRECTIVE_STATUS Description NOT_CONFIGURED System Meta pointer is NULL or corrupt INCORRECT_STATE Init Meta pointer set in init state or Scheduling not started or System time is not initialized (check log for more information)
INTERNAL_ERROR Semaphore fixed data pointer is NULL or (check log for more information) INVALID_ID Semaphore id is not OK UNSATISFIED Called without timeout initialisation, semaphore was created with use_timeout = FALSE or Job was started as a result of a timeout on this semaphore (check log for more information)
TOO_MANY Semaphore pending queue is full SUCCESSFUL All OK Example Usage
enum SEM_NAME{ s_tesla, s_audi }; enum DIRECTIVE_STATUS status; status = oceos_sem_wait_restart_timeout(s_tesla, 10000); if(SUCCESSFUL != status) { // Handle ERROR }
oceos_sem_get_value()
Header File
semaphore.h
Description
Returns number of available permits for semaphore ID.Prototype
int oceos_sem_get_value( sem_t sem_id // counting semaphore ID );Parameters
Parameter Description sem_id Counting Semaphore ID Returns
This function returns int.
int Description -1 ERROR >= 0 Number of available permits Example Usage
enum SEM_NAME{ s_tesla, s_audi }; int count; count = oceos_sem_get_value(s_tesla); if(-1 == count) { // Handle ERROR }
oceos_sem_penq_get_size()
Header File
semaphore.h
Description
Returns number of jobs on semaphore pending queue for semaphore ID.Prototype
int oceos_sem_penq_get_size( sem_t sem_id // counting semaphore ID );Parameters
Parameter Description sem_id Counting Semaphore ID Returns
This function returns int.
int Description -1 ERROR >= 0 Number of jobs on semaphore pending queue Example Usage
enum SEM_NAME{ s_tesla, s_audi }; int count; count = oceos_sem_penq_get_size(s_tesla); if(-1 == count) { // Handle ERROR }
oceos_sem_reset()
Header File
semaphore.h
Description
Restore permits to original value and remove jobs from pending queue.Prototype
enum DIRECTIVE_STATUS oceos_sem_reset( sem_t sem_id // counting semaphore ID );Parameters
Parameter Description sem_id Counting Semaphore ID Returns
This function returns enum DIRECTIVE_STATUS.
enum DIRECTIVE_STATUS Description INCORRECT_STATE Initialization phase is not finished or scheduling not started INTERNAL_ERROR Semaphore fixed data pointer is NULL or (check log for more information) INVALID_ID Semaphore id is not OK SUCCESSFUL All OK Example Usage
enum SEM_NAME{ s_tesla, s_audi }; enum DIRECTIVE_STATUS status; status = oceos_sem_reset(s_tesla); if(SUCCESSFUL != status) { // Handle ERROR }