12.3. Operations

12.3.1. Creating a Semaphore

The rtems_semaphore_create directive creates a binary or counting semaphore with a user-specified name as well as an initial count. If a binary semaphore is created with a count of zero (0) to indicate that it has been allocated, then the task creating the semaphore is considered the current holder of the semaphore. At create time the method for ordering waiting tasks in the semaphore’s task wait queue (by FIFO or task priority) is specified. Additionally, the priority inheritance or priority ceiling algorithm may be selected for local, binary semaphores that use the priority task wait queue blocking discipline. If the priority ceiling algorithm is selected, then the highest priority of any task which will attempt to obtain this semaphore must be specified. RTEMS allocates a Semaphore Control Block (SMCB) from the SMCB free list. This data structure is used by RTEMS to manage the newly created semaphore. Also, a unique semaphore ID is generated and returned to the calling task.

12.3.2. Obtaining Semaphore IDs

When a semaphore is created, RTEMS generates a unique semaphore ID and assigns it to the created semaphore until it is deleted. The semaphore ID may be obtained by either of two methods. First, as the result of an invocation of the rtems_semaphore_create directive, the semaphore ID is stored in a user provided location. Second, the semaphore ID may be obtained later using the rtems_semaphore_ident directive. The semaphore ID is used by other semaphore manager directives to access this semaphore.

12.3.3. Acquiring a Semaphore

The rtems_semaphore_obtain directive is used to acquire the specified semaphore. A simplified version of the rtems_semaphore_obtain directive can be described as follows:

If the semaphore’s count is greater than zero then decrement the semaphore’s count else wait for release of semaphore then return SUCCESSFUL.

When the semaphore cannot be immediately acquired, one of the following situations applies:

  • By default, the calling task will wait forever to acquire the semaphore.

  • Specifying RTEMS_NO_WAIT forces an immediate return with an error status code.

  • Specifying a timeout limits the interval the task will wait before returning with an error status code.

If the task waits to acquire the semaphore, then it is placed in the semaphore’s task wait queue in either FIFO or task priority order. If the task blocked waiting for a binary semaphore using priority inheritance and the task’s priority is greater than that of the task currently holding the semaphore, then the holding task will inherit the priority of the blocking task. All tasks waiting on a semaphore are returned an error code when the semaphore is deleted.

When a task successfully obtains a semaphore using priority ceiling and the priority ceiling for this semaphore is greater than that of the holder, then the holder’s priority will be elevated.

12.3.4. Releasing a Semaphore

The rtems_semaphore_release directive is used to release the specified semaphore. A simplified version of the rtems_semaphore_release directive can be described as follows:

If there are no tasks are waiting on this semaphore then increment the semaphore’s count else assign semaphore to a waiting task and return SUCCESSFUL.

If this is the outermost release of a binary semaphore that uses priority inheritance or priority ceiling and the task does not currently hold any other binary semaphores, then the task performing the rtems_semaphore_release will have its priority restored to its normal value.

12.3.5. Deleting a Semaphore

The rtems_semaphore_delete directive removes a semaphore from the system and frees its control block. A semaphore can be deleted by any local task that knows the semaphore’s ID. As a result of this directive, all tasks blocked waiting to acquire the semaphore will be readied and returned a status code which indicates that the semaphore was deleted. Any subsequent references to the semaphore’s name and ID are invalid.