OCEOS/oceos inter-task communication/semaphore

From wiki
Jump to navigation Jump to search

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

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 here

Prototype

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
}