mirror of
https://git.rtems.org/rtems-docs/
synced 2025-05-16 01:36:40 +08:00
c-user: Split up semaphore manager
This makes it easier to automatically generate parts of the manager documentation in the future. Update #3993.
This commit is contained in:
parent
bd8185a7dd
commit
16ee8cf45b
@ -35,7 +35,7 @@ RTEMS Classic API Guide (|version|).
|
|||||||
clock_manager
|
clock_manager
|
||||||
timer_manager
|
timer_manager
|
||||||
rate_monotonic_manager
|
rate_monotonic_manager
|
||||||
semaphore_manager
|
semaphore/index
|
||||||
barrier_manager
|
barrier_manager
|
||||||
message_manager
|
message_manager
|
||||||
event_manager
|
event_manager
|
||||||
|
180
c-user/semaphore/background.rst
Normal file
180
c-user/semaphore/background.rst
Normal file
@ -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``.
|
@ -2,315 +2,6 @@
|
|||||||
|
|
||||||
.. Copyright (C) 1988, 2008 On-Line Applications Research Corporation (OAR)
|
.. Copyright (C) 1988, 2008 On-Line Applications Research Corporation (OAR)
|
||||||
|
|
||||||
.. index:: semaphores
|
|
||||||
.. index:: binary semaphores
|
|
||||||
.. index:: counting semaphores
|
|
||||||
.. index:: mutual exclusion
|
|
||||||
|
|
||||||
Semaphore Manager
|
|
||||||
*****************
|
|
||||||
|
|
||||||
Introduction
|
|
||||||
============
|
|
||||||
|
|
||||||
The semaphore manager utilizes standard Dijkstra
|
|
||||||
counting semaphores to provide synchronization and mutual
|
|
||||||
exclusion capabilities. The directives provided by the
|
|
||||||
semaphore manager are:
|
|
||||||
|
|
||||||
- rtems_semaphore_create_ - Create a semaphore
|
|
||||||
|
|
||||||
- rtems_semaphore_ident_ - Get ID of a semaphore
|
|
||||||
|
|
||||||
- rtems_semaphore_delete_ - Delete a semaphore
|
|
||||||
|
|
||||||
- rtems_semaphore_obtain_ - Acquire a semaphore
|
|
||||||
|
|
||||||
- rtems_semaphore_release_ - Release a semaphore
|
|
||||||
|
|
||||||
- rtems_semaphore_flush_ - Unblock all tasks waiting on a semaphore
|
|
||||||
|
|
||||||
- rtems_semaphore_set_priority_ - Set priority by scheduler for a semaphore
|
|
||||||
|
|
||||||
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``.
|
|
||||||
|
|
||||||
Operations
|
|
||||||
==========
|
|
||||||
|
|
||||||
.. _Creating a Semaphore:
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
.. _Obtaining Semaphore IDs:
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
.. _Acquiring a Semaphore:
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
.. _Releasing a Semaphore:
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
.. _Deleting a Semaphore:
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
Directives
|
Directives
|
||||||
==========
|
==========
|
||||||
|
|
18
c-user/semaphore/index.rst
Normal file
18
c-user/semaphore/index.rst
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
.. SPDX-License-Identifier: CC-BY-SA-4.0
|
||||||
|
|
||||||
|
.. Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
|
||||||
|
|
||||||
|
.. index:: semaphores
|
||||||
|
.. index:: binary semaphores
|
||||||
|
.. index:: counting semaphores
|
||||||
|
.. index:: mutual exclusion
|
||||||
|
|
||||||
|
Semaphore Manager
|
||||||
|
*****************
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
|
||||||
|
introduction
|
||||||
|
background
|
||||||
|
operations
|
||||||
|
directives
|
25
c-user/semaphore/introduction.rst
Normal file
25
c-user/semaphore/introduction.rst
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
.. SPDX-License-Identifier: CC-BY-SA-4.0
|
||||||
|
|
||||||
|
.. Copyright (C) 1988, 2008 On-Line Applications Research Corporation (OAR)
|
||||||
|
|
||||||
|
Introduction
|
||||||
|
============
|
||||||
|
|
||||||
|
The semaphore manager utilizes standard Dijkstra
|
||||||
|
counting semaphores to provide synchronization and mutual
|
||||||
|
exclusion capabilities. The directives provided by the
|
||||||
|
semaphore manager are:
|
||||||
|
|
||||||
|
- :ref:`rtems_semaphore_create`
|
||||||
|
|
||||||
|
- :ref:`rtems_semaphore_ident`
|
||||||
|
|
||||||
|
- :ref:`rtems_semaphore_delete`
|
||||||
|
|
||||||
|
- :ref:`rtems_semaphore_obtain`
|
||||||
|
|
||||||
|
- :ref:`rtems_semaphore_release`
|
||||||
|
|
||||||
|
- :ref:`rtems_semaphore_flush`
|
||||||
|
|
||||||
|
- :ref:`rtems_semaphore_set_priority`
|
105
c-user/semaphore/operations.rst
Normal file
105
c-user/semaphore/operations.rst
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
.. SPDX-License-Identifier: CC-BY-SA-4.0
|
||||||
|
|
||||||
|
.. Copyright (C) 1988, 2008 On-Line Applications Research Corporation (OAR)
|
||||||
|
|
||||||
|
Operations
|
||||||
|
==========
|
||||||
|
|
||||||
|
.. _Creating a Semaphore:
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
.. _Obtaining Semaphore IDs:
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
.. _Acquiring a Semaphore:
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
.. _Releasing a Semaphore:
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
.. _Deleting a Semaphore:
|
||||||
|
|
||||||
|
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.
|
Loading…
x
Reference in New Issue
Block a user