diff options
Diffstat (limited to 'c-user/semaphore/background.rst')
-rw-r--r-- | c-user/semaphore/background.rst | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/c-user/semaphore/background.rst b/c-user/semaphore/background.rst new file mode 100644 index 0000000..9d9b151 --- /dev/null +++ b/c-user/semaphore/background.rst @@ -0,0 +1,180 @@ +.. SPDX-License-Identifier: CC-BY-SA-4.0 + +.. Copyright (C) 1988, 2008 On-Line Applications Research Corporation (OAR) + +Background +========== + +A semaphore can be viewed as a protected variable whose value can be modified +only with the ``rtems_semaphore_create``, ``rtems_semaphore_obtain``, and +``rtems_semaphore_release`` directives. RTEMS supports both binary and +counting semaphores. A binary semaphore is restricted to values of zero or one, +while a counting semaphore can assume any non-negative integer value. + +A binary semaphore (not a simple binary semaphore) can be used to control +access to a single resource. In particular, it can be used to enforce mutual +exclusion for a critical section in user code (mutex). In this instance, the +semaphore would be created with an initial count of one to indicate that no +task is executing the critical section of code. Upon entry to the critical +section, a task must issue the ``rtems_semaphore_obtain`` directive to prevent +other tasks from entering the critical section. Upon exit from the critical +section, the task that obtained the binary semaphore must issue the +``rtems_semaphore_release`` directive to allow another task to execute the +critical section. A binary semaphore must be released by the task that +obtained it. + +A counting semaphore can be used to control access to a pool of two or more +resources. For example, access to three printers could be administered by a +semaphore created with an initial count of three. When a task requires access +to one of the printers, it issues the ``rtems_semaphore_obtain`` directive to +obtain access to a printer. If a printer is not currently available, the task +can wait for a printer to become available or return immediately. When the +task has completed printing, it should issue the ``rtems_semaphore_release`` +directive to allow other tasks access to the printer. + +Task synchronization may be achieved by creating a semaphore with an initial +count of zero. One task waits for the arrival of another task by issuing a +``rtems_semaphore_obtain`` directive when it reaches a synchronization point. +The other task performs a corresponding ``rtems_semaphore_release`` operation +when it reaches its synchronization point, thus unblocking the pending task. + +.. _Nested Resource Access: + +Nested Resource Access +---------------------- + +Deadlock occurs when a task owning a binary semaphore attempts to acquire that +same semaphore and blocks as result. Since the semaphore is allocated to a +task, it cannot be deleted. Therefore, the task that currently holds the +semaphore and is also blocked waiting for that semaphore will never execute +again. + +RTEMS addresses this problem by allowing the task holding the binary semaphore +to obtain the same binary semaphore multiple times in a nested manner. Each +``rtems_semaphore_obtain`` must be accompanied with a +``rtems_semaphore_release``. The semaphore will only be made available for +acquisition by other tasks when the outermost ``rtems_semaphore_obtain`` is +matched with a ``rtems_semaphore_release``. + +Simple binary semaphores do not allow nested access and so can be used for task +synchronization. + +.. _Priority Inheritance: + +Priority Inheritance +-------------------- + +RTEMS supports :ref:`priority inheritance <PriorityInheritance>` for local, +binary semaphores that use the priority task wait queue blocking discipline. +In SMP configurations, the :ref:`OMIP` is used instead. + +.. _Priority Ceiling: + +Priority Ceiling +---------------- + +RTEMS supports :ref:`priority ceiling <PriorityCeiling>` for local, binary +semaphores that use the priority task wait queue blocking discipline. + +.. _Multiprocessor Resource Sharing Protocol: + +Multiprocessor Resource Sharing Protocol +---------------------------------------- + +RTEMS supports the :ref:`MrsP` for local, binary semaphores that use the +priority task wait queue blocking discipline. In uniprocessor configurations, +the :ref:`PriorityCeiling` is used instead. + +.. _Building a Semaphore Attribute Set: + +Building a Semaphore Attribute Set +---------------------------------- + +In general, an attribute set is built by a bitwise OR of the desired attribute +components. The following table lists the set of valid semaphore attributes: + +.. list-table:: + :class: rtems-table + + * - ``RTEMS_FIFO`` + - tasks wait by FIFO (default) + * - ``RTEMS_PRIORITY`` + - tasks wait by priority + * - ``RTEMS_BINARY_SEMAPHORE`` + - restrict values to 0 and 1 + * - ``RTEMS_COUNTING_SEMAPHORE`` + - no restriction on values (default) + * - ``RTEMS_SIMPLE_BINARY_SEMAPHORE`` + - restrict values to 0 and 1, do not allow nested access, allow deletion of + locked semaphore. + * - ``RTEMS_NO_INHERIT_PRIORITY`` + - do not use priority inheritance (default) + * - ``RTEMS_INHERIT_PRIORITY`` + - use priority inheritance + * - ``RTEMS_NO_PRIORITY_CEILING`` + - do not use priority ceiling (default) + * - ``RTEMS_PRIORITY_CEILING`` + - use priority ceiling + * - ``RTEMS_NO_MULTIPROCESSOR_RESOURCE_SHARING`` + - do not use Multiprocessor Resource Sharing Protocol (default) + * - ``RTEMS_MULTIPROCESSOR_RESOURCE_SHARING`` + - use Multiprocessor Resource Sharing Protocol + * - ``RTEMS_LOCAL`` + - local semaphore (default) + * - ``RTEMS_GLOBAL`` + - global semaphore + +Attribute values are specifically designed to be mutually exclusive, therefore +bitwise OR and addition operations are equivalent as long as each attribute +appears exactly once in the component list. An attribute listed as a default +is not required to appear in the attribute list, although it is a good +programming practice to specify default attributes. If all defaults are +desired, the attribute ``RTEMS_DEFAULT_ATTRIBUTES`` should be specified on this +call. + +This example demonstrates the attribute_set parameter needed to create a local +semaphore with the task priority waiting queue discipline. The attribute_set +parameter passed to the ``rtems_semaphore_create`` directive could be either +``RTEMS_PRIORITY`` or ``RTEMS_LOCAL | RTEMS_PRIORITY``. The attribute_set +parameter can be set to ``RTEMS_PRIORITY`` because ``RTEMS_LOCAL`` is the +default for all created tasks. If a similar semaphore were to be known +globally, then the attribute_set parameter would be ``RTEMS_GLOBAL | +RTEMS_PRIORITY``. + +Some combinatinos of these attributes are invalid. For example, priority +ordered blocking discipline must be applied to a binary semaphore in order to +use either the priority inheritance or priority ceiling functionality. The +following tree figure illustrates the valid combinations. + +.. figure:: ../../images/c_user/semaphore_attributes.png + :width: 90% + :align: center + :alt: Semaphore Attributes + +.. _Building a SEMAPHORE_OBTAIN Option Set: + +Building a SEMAPHORE_OBTAIN Option Set +-------------------------------------- + +In general, an option is built by a bitwise OR of the desired option +components. The set of valid options for the ``rtems_semaphore_obtain`` +directive are listed in the following table: + +.. list-table:: + :class: rtems-table + + * - ``RTEMS_WAIT`` + - task will wait for semaphore (default) + * - ``RTEMS_NO_WAIT`` + - task should not wait + +Option values are specifically designed to be mutually exclusive, therefore +bitwise OR and addition operations are equivalent as long as each attribute +appears exactly once in the component list. An option listed as a default is +not required to appear in the list, although it is a good programming practice +to specify default options. If all defaults are desired, the option +``RTEMS_DEFAULT_OPTIONS`` should be specified on this call. + +This example demonstrates the option parameter needed to poll for a semaphore. +The option parameter passed to the ``rtems_semaphore_obtain`` directive should +be ``RTEMS_NO_WAIT``. |