summaryrefslogtreecommitdiffstats
path: root/c_user/semaphore_manager.rst
diff options
context:
space:
mode:
Diffstat (limited to 'c_user/semaphore_manager.rst')
-rw-r--r--c_user/semaphore_manager.rst926
1 files changed, 926 insertions, 0 deletions
diff --git a/c_user/semaphore_manager.rst b/c_user/semaphore_manager.rst
new file mode 100644
index 0000000..38f1a60
--- /dev/null
+++ b/c_user/semaphore_manager.rst
@@ -0,0 +1,926 @@
+Semaphore Manager
+#################
+
+.. index:: semaphores
+.. index:: binary semaphores
+.. index:: counting semaphores
+.. index:: mutual exclusion
+
+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 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. 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 must issue the``rtems_semaphore_release`` directive to
+allow another task to execute the critical section.
+
+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
+----------------------
+
+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 Inversion
+------------------
+
+Priority inversion is a form of indefinite
+postponement which is common in multitasking, preemptive
+executives with shared resources. Priority inversion occurs
+when a high priority tasks requests access to shared resource
+which is currently allocated to low priority task. The high
+priority task must block until the low priority task releases
+the resource. This problem is exacerbated when the low priority
+task is prevented from executing by one or more medium priority
+tasks. Because the low priority task is not executing, it
+cannot complete its interaction with the resource and release
+that resource. The high priority task is effectively prevented
+from executing by lower priority tasks.
+
+
+Priority Inheritance
+--------------------
+
+Priority inheritance is an algorithm that calls for
+the lower priority task holding a resource to have its priority
+increased to that of the highest priority task blocked waiting
+for that resource. Each time a task blocks attempting to obtain
+the resource, the task holding the resource may have its
+priority increased.
+
+On SMP configurations, in case the task holding the resource and the task that
+blocks attempting to obtain the resource are in different scheduler instances,
+the priority of the holder is raised to the pseudo-interrupt priority (priority
+boosting). The pseudo-interrupt priority is the highest priority.
+
+RTEMS supports priority inheritance for local, binary
+semaphores that use the priority task wait queue blocking
+discipline. When a task of higher priority than the task
+holding the semaphore blocks, the priority of the task holding
+the semaphore is increased to that of the blocking task. When
+the task holding the task completely releases the binary
+semaphore (i.e. not for a nested release), the holder’s priority
+is restored to the value it had before any higher priority was
+inherited.
+
+The RTEMS implementation of the priority inheritance
+algorithm takes into account the scenario in which a task holds
+more than one binary semaphore. The holding task will execute
+at the priority of the higher of the highest ceiling priority or
+at the priority of the highest priority task blocked waiting for
+any of the semaphores the task holds. Only when the task
+releases ALL of the binary semaphores it holds will its priority
+be restored to the normal value.
+
+Priority Ceiling
+----------------
+
+Priority ceiling is an algorithm that calls for the
+lower priority task holding a resource to have its priority
+increased to that of the highest priority task which will EVER
+block waiting for that resource. This algorithm addresses the
+problem of priority inversion although it avoids the possibility
+of changing the priority of the task holding the resource
+multiple times. The priority ceiling algorithm will only change
+the priority of the task holding the resource a maximum of one
+time. The ceiling priority is set at creation time and must be
+the priority of the highest priority task which will ever
+attempt to acquire that semaphore.
+
+RTEMS supports priority ceiling for local, binary
+semaphores that use the priority task wait queue blocking
+discipline. When a task of lower priority than the ceiling
+priority successfully obtains the semaphore, its priority is
+raised to the ceiling priority. When the task holding the task
+completely releases the binary semaphore (i.e. not for a nested
+release), the holder’s priority is restored to the value it had
+before any higher priority was put into effect.
+
+The need to identify the highest priority task which
+will attempt to obtain a particular semaphore can be a difficult
+task in a large, complicated system. Although the priority
+ceiling algorithm is more efficient than the priority
+inheritance algorithm with respect to the maximum number of task
+priority changes which may occur while a task holds a particular
+semaphore, the priority inheritance algorithm is more forgiving
+in that it does not require this apriori information.
+
+The RTEMS implementation of the priority ceiling
+algorithm takes into account the scenario in which a task holds
+more than one binary semaphore. The holding task will execute
+at the priority of the higher of the highest ceiling priority or
+at the priority of the highest priority task blocked waiting for
+any of the semaphores the task holds. Only when the task
+releases ALL of the binary semaphores it holds will its priority
+be restored to the normal value.
+
+
+Multiprocessor Resource Sharing Protocol
+----------------------------------------
+
+The Multiprocessor Resource Sharing Protocol (MrsP) is defined in *A.
+Burns and A.J. Wellings, A Schedulability Compatible Multiprocessor Resource
+Sharing Protocol - MrsP, Proceedings of the 25th Euromicro Conference on
+Real-Time Systems (ECRTS 2013), July 2013*. It is a generalization of the
+Priority Ceiling Protocol to SMP systems. Each MrsP semaphore uses a ceiling
+priority per scheduler instance. These ceiling priorities can be specified
+with ``rtems_semaphore_set_priority()``. A task obtaining or owning a MrsP
+semaphore will execute with the ceiling priority for its scheduler instance as
+specified by the MrsP semaphore object. Tasks waiting to get ownership of a
+MrsP semaphore will not relinquish the processor voluntarily. In case the
+owner of a MrsP semaphore gets preempted it can ask all tasks waiting for this
+semaphore to help out and temporarily borrow the right to execute on one of
+their assigned processors.
+
+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:
+
+- ``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.
+
+.. code:: c
+
+ Not available in ASCII representation
+
+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:
+
+- ``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
+--------------------
+
+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
+-----------------------
+
+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
+---------------------
+
+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:
+.. code:: c
+
+ if semaphore's count is greater than zero
+ then decrement semaphore's count
+ else wait for release of semaphore
+ 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
+---------------------
+
+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:
+.. code:: c
+
+ if no tasks are waiting on this semaphore
+ then increment semaphore's count
+ else assign semaphore to a waiting task
+ 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
+--------------------
+
+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
+==========
+
+This section details the semaphore manager’s
+directives. A subsection is dedicated to each of this manager’s
+directives and describes the calling sequence, related
+constants, usage, and status codes.
+
+SEMAPHORE_CREATE - Create a semaphore
+-------------------------------------
+.. index:: create a semaphore
+
+**CALLING SEQUENCE:**
+
+.. index:: rtems_semaphore_create
+
+.. code:: c
+
+ rtems_status_code rtems_semaphore_create(
+ rtems_name name,
+ uint32_t count,
+ rtems_attribute attribute_set,
+ rtems_task_priority priority_ceiling,
+ rtems_id \*id
+ );
+
+**DIRECTIVE STATUS CODES:**
+
+``RTEMS_SUCCESSFUL`` - semaphore created successfully
+``RTEMS_INVALID_NAME`` - invalid semaphore name
+``RTEMS_INVALID_ADDRESS`` - ``id`` is NULL
+``RTEMS_TOO_MANY`` - too many semaphores created
+``RTEMS_NOT_DEFINED`` - invalid attribute set
+``RTEMS_INVALID_NUMBER`` - invalid starting count for binary semaphore
+``RTEMS_MP_NOT_CONFIGURED`` - multiprocessing not configured
+``RTEMS_TOO_MANY`` - too many global objects
+
+**DESCRIPTION:**
+
+This directive creates a semaphore which resides on
+the local node. The created semaphore has the user-defined name
+specified in name and the initial count specified in count. For
+control and maintenance of the semaphore, RTEMS allocates and
+initializes a SMCB. The RTEMS-assigned semaphore id is returned
+in id. This semaphore id is used with other semaphore related
+directives to access the semaphore.
+
+Specifying PRIORITY in attribute_set causes tasks
+waiting for a semaphore to be serviced according to task
+priority. When FIFO is selected, tasks are serviced in First
+In-First Out order.
+
+**NOTES:**
+
+This directive will not cause the calling task to be
+preempted.
+
+The priority inheritance and priority ceiling
+algorithms are only supported for local, binary semaphores that
+use the priority task wait queue blocking discipline.
+
+The following semaphore attribute constants are
+defined by RTEMS:
+
+- ``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, block on 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
+
+Semaphores should not be made global unless remote
+tasks must interact with the created semaphore. This is to
+avoid the system overhead incurred by the creation of a global
+semaphore. When a global semaphore is created, the semaphore’s
+name and id must be transmitted to every node in the system for
+insertion in the local copy of the global object table.
+
+Note that some combinations of attributes are not valid. See the
+earlier discussion on this.
+
+The total number of global objects, including semaphores, is limited by
+the maximum_global_objects field in the Configuration Table.
+
+It is not allowed to create an initially locked MrsP semaphore and the``RTEMS_INVALID_NUMBER`` status code will be returned on SMP
+configurations in this case. This prevents lock order reversal problems with
+the allocator mutex.
+
+SEMAPHORE_IDENT - Get ID of a semaphore
+---------------------------------------
+.. index:: get ID of a semaphore
+.. index:: obtain ID of a semaphore
+
+**CALLING SEQUENCE:**
+
+.. index:: rtems_semaphore_ident
+
+.. code:: c
+
+ rtems_status_code rtems_semaphore_ident(
+ rtems_name name,
+ uint32_t node,
+ rtems_id \*id
+ );
+
+**DIRECTIVE STATUS CODES:**
+
+``RTEMS_SUCCESSFUL`` - semaphore identified successfully
+``RTEMS_INVALID_NAME`` - semaphore name not found
+``RTEMS_INVALID_NODE`` - invalid node id
+
+**DESCRIPTION:**
+
+This directive obtains the semaphore id associated
+with the semaphore name. If the semaphore name is not unique,
+then the semaphore id will match one of the semaphores with that
+name. However, this semaphore id is not guaranteed to
+correspond to the desired semaphore. The semaphore id is used
+by other semaphore related directives to access the semaphore.
+
+**NOTES:**
+
+This directive will not cause the running task to be
+preempted.
+
+If node is ``RTEMS_SEARCH_ALL_NODES``, all nodes are searched
+with the local node being searched first. All other nodes are
+searched with the lowest numbered node searched first.
+
+If node is a valid node number which does not
+represent the local node, then only the semaphores exported by
+the designated node are searched.
+
+This directive does not generate activity on remote
+nodes. It accesses only the local copy of the global object
+table.
+
+SEMAPHORE_DELETE - Delete a semaphore
+-------------------------------------
+.. index:: delete a semaphore
+
+**CALLING SEQUENCE:**
+
+.. index:: rtems_semaphore_delete
+
+.. code:: c
+
+ rtems_status_code rtems_semaphore_delete(
+ rtems_id id
+ );
+
+**DIRECTIVE STATUS CODES:**
+
+``RTEMS_SUCCESSFUL`` - semaphore deleted successfully
+``RTEMS_INVALID_ID`` - invalid semaphore id
+``RTEMS_RESOURCE_IN_USE`` - binary semaphore is in use
+``RTEMS_ILLEGAL_ON_REMOTE_OBJECT`` - cannot delete remote semaphore
+
+**DESCRIPTION:**
+
+This directive deletes the semaphore specified by ``id``.
+All tasks blocked waiting to acquire the semaphore will be
+readied and returned a status code which indicates that the
+semaphore was deleted. The SMCB for this semaphore is reclaimed
+by RTEMS.
+
+**NOTES:**
+
+The calling task will be preempted if it is enabled
+by the task’s execution mode and a higher priority local task is
+waiting on the deleted semaphore. The calling task will NOT be
+preempted if all of the tasks that are waiting on the semaphore
+are remote tasks.
+
+The calling task does not have to be the task that
+created the semaphore. Any local task that knows the semaphore
+id can delete the semaphore.
+
+When a global semaphore is deleted, the semaphore id
+must be transmitted to every node in the system for deletion
+from the local copy of the global object table.
+
+The semaphore must reside on the local node, even if
+the semaphore was created with the ``RTEMS_GLOBAL`` option.
+
+Proxies, used to represent remote tasks, are
+reclaimed when the semaphore is deleted.
+
+SEMAPHORE_OBTAIN - Acquire a semaphore
+--------------------------------------
+.. index:: obtain a semaphore
+.. index:: lock a semaphore
+
+**CALLING SEQUENCE:**
+
+.. index:: rtems_semaphore_obtain
+
+.. code:: c
+
+ rtems_status_code rtems_semaphore_obtain(
+ rtems_id id,
+ rtems_option option_set,
+ rtems_interval timeout
+ );
+
+**DIRECTIVE STATUS CODES:**
+
+``RTEMS_SUCCESSFUL`` - semaphore obtained successfully
+``RTEMS_UNSATISFIED`` - semaphore not available
+``RTEMS_TIMEOUT`` - timed out waiting for semaphore
+``RTEMS_OBJECT_WAS_DELETED`` - semaphore deleted while waiting
+``RTEMS_INVALID_ID`` - invalid semaphore id
+
+**DESCRIPTION:**
+
+This directive acquires the semaphore specified by
+id. The ``RTEMS_WAIT`` and ``RTEMS_NO_WAIT`` components of the options parameter
+indicate whether the calling task wants to wait for the
+semaphore to become available or return immediately if the
+semaphore is not currently available. With either ``RTEMS_WAIT`` or``RTEMS_NO_WAIT``, if the current semaphore count is positive, then it is
+decremented by one and the semaphore is successfully acquired by
+returning immediately with a successful return code.
+
+If the calling task chooses to return immediately and the current
+semaphore count is zero or negative, then a status code is returned
+indicating that the semaphore is not available. If the calling task
+chooses to wait for a semaphore and the current semaphore count is zero or
+negative, then it is decremented by one and the calling task is placed on
+the semaphore’s wait queue and blocked. If the semaphore was created with
+the ``RTEMS_PRIORITY`` attribute, then the calling task is
+inserted into the queue according to its priority. However, if the
+semaphore was created with the ``RTEMS_FIFO`` attribute, then
+the calling task is placed at the rear of the wait queue. If the binary
+semaphore was created with the ``RTEMS_INHERIT_PRIORITY``
+attribute, then the priority of the task currently holding the binary
+semaphore is guaranteed to be greater than or equal to that of the
+blocking task. If the binary semaphore was created with the``RTEMS_PRIORITY_CEILING`` attribute, a task successfully
+obtains the semaphore, and the priority of that task is greater than the
+ceiling priority for this semaphore, then the priority of the task
+obtaining the semaphore is elevated to that of the ceiling.
+
+The timeout parameter specifies the maximum interval the calling task is
+willing to be blocked waiting for the semaphore. If it is set to``RTEMS_NO_TIMEOUT``, then the calling task will wait forever.
+If the semaphore is available or the ``RTEMS_NO_WAIT`` option
+component is set, then timeout is ignored.
+
+Deadlock situations are detected for MrsP semaphores and the``RTEMS_UNSATISFIED`` status code will be returned on SMP
+configurations in this case.
+
+**NOTES:**
+
+The following semaphore acquisition option constants
+are defined by RTEMS:
+
+- ``RTEMS_WAIT`` - task will wait for semaphore (default)
+
+- ``RTEMS_NO_WAIT`` - task should not wait
+
+Attempting to obtain a global semaphore which does not reside on the local
+node will generate a request to the remote node to access the semaphore.
+If the semaphore is not available and ``RTEMS_NO_WAIT`` was
+not specified, then the task must be blocked until the semaphore is
+released. A proxy is allocated on the remote node to represent the task
+until the semaphore is released.
+
+A clock tick is required to support the timeout functionality of
+this directive.
+
+It is not allowed to obtain a MrsP semaphore more than once by one task at a
+time (nested access) and the ``RTEMS_UNSATISFIED`` status code will
+be returned on SMP configurations in this case.
+
+SEMAPHORE_RELEASE - Release a semaphore
+---------------------------------------
+.. index:: release a semaphore
+.. index:: unlock a semaphore
+
+**CALLING SEQUENCE:**
+
+.. index:: rtems_semaphore_release
+
+.. code:: c
+
+ rtems_status_code rtems_semaphore_release(
+ rtems_id id
+ );
+
+**DIRECTIVE STATUS CODES:**
+
+``RTEMS_SUCCESSFUL`` - semaphore released successfully
+``RTEMS_INVALID_ID`` - invalid semaphore id
+``RTEMS_NOT_OWNER_OF_RESOURCE`` - calling task does not own semaphore
+``RTEMS_INCORRECT_STATE`` - invalid unlock order
+
+**DESCRIPTION:**
+
+This directive releases the semaphore specified by
+id. The semaphore count is incremented by one. If the count is
+zero or negative, then the first task on this semaphore’s wait
+queue is removed and unblocked. The unblocked task may preempt
+the running task if the running task’s preemption mode is
+enabled and the unblocked task has a higher priority than the
+running task.
+
+**NOTES:**
+
+The calling task may be preempted if it causes a
+higher priority task to be made ready for execution.
+
+Releasing a global semaphore which does not reside on
+the local node will generate a request telling the remote node
+to release the semaphore.
+
+If the task to be unblocked resides on a different
+node from the semaphore, then the semaphore allocation is
+forwarded to the appropriate node, the waiting task is
+unblocked, and the proxy used to represent the task is reclaimed.
+
+The outermost release of a local, binary, priority
+inheritance or priority ceiling semaphore may result in the
+calling task having its priority lowered. This will occur if
+the calling task holds no other binary semaphores and it has
+inherited a higher priority.
+
+The MrsP semaphores must be released in the reversed obtain order, otherwise
+the ``RTEMS_INCORRECT_STATE`` status code will be returned on SMP
+configurations in this case.
+
+SEMAPHORE_FLUSH - Unblock all tasks waiting on a semaphore
+----------------------------------------------------------
+.. index:: flush a semaphore
+.. index:: unblock all tasks waiting on a semaphore
+
+**CALLING SEQUENCE:**
+
+.. index:: rtems_semaphore_flush
+
+.. code:: c
+
+ rtems_status_code rtems_semaphore_flush(
+ rtems_id id
+ );
+
+**DIRECTIVE STATUS CODES:**
+
+``RTEMS_SUCCESSFUL`` - semaphore released successfully
+``RTEMS_INVALID_ID`` - invalid semaphore id
+``RTEMS_NOT_DEFINED`` - operation not defined for the protocol of
+the semaphore
+``RTEMS_ILLEGAL_ON_REMOTE_OBJECT`` - not supported for remote semaphores
+
+**DESCRIPTION:**
+
+This directive unblocks all tasks waiting on the semaphore specified by
+id. Since there are tasks blocked on the semaphore, the semaphore’s
+count is not changed by this directive and thus is zero before and
+after this directive is executed. Tasks which are unblocked as the
+result of this directive will return from the``rtems_semaphore_obtain`` directive with a
+status code of ``RTEMS_UNSATISFIED`` to indicate
+that the semaphore was not obtained.
+
+This directive may unblock any number of tasks. Any of the unblocked
+tasks may preempt the running task if the running task’s preemption mode is
+enabled and an unblocked task has a higher priority than the
+running task.
+
+**NOTES:**
+
+The calling task may be preempted if it causes a
+higher priority task to be made ready for execution.
+
+If the task to be unblocked resides on a different
+node from the semaphore, then the waiting task is
+unblocked, and the proxy used to represent the task is reclaimed.
+
+It is not allowed to flush a MrsP semaphore and the``RTEMS_NOT_DEFINED`` status code will be returned on SMP
+configurations in this case.
+
+SEMAPHORE_SET_PRIORITY - Set priority by scheduler for a semaphore
+------------------------------------------------------------------
+.. index:: set priority by scheduler for a semaphore
+
+**CALLING SEQUENCE:**
+
+.. index:: rtems_semaphore_set_priority
+
+.. code:: c
+
+ rtems_status_code rtems_semaphore_set_priority(
+ rtems_id semaphore_id,
+ rtems_id scheduler_id,
+ rtems_task_priority new_priority,
+ rtems_task_priority \*old_priority
+ );
+
+**DIRECTIVE STATUS CODES:**
+
+``RTEMS_SUCCESSFUL`` - successful operation
+``RTEMS_INVALID_ID`` - invalid semaphore or scheduler id
+``RTEMS_INVALID_ADDRESS`` - ``old_priority`` is NULL
+``RTEMS_INVALID_PRIORITY`` - invalid new priority value
+``RTEMS_NOT_DEFINED`` - operation not defined for the protocol of
+the semaphore
+``RTEMS_ILLEGAL_ON_REMOTE_OBJECT`` - not supported for remote semaphores
+
+**DESCRIPTION:**
+
+This directive sets the priority value with respect to the specified scheduler
+of a semaphore.
+
+The special priority value ``RTEMS_CURRENT_PRIORITY`` can be used to get the
+current priority value without changing it.
+
+The interpretation of the priority value depends on the protocol of the
+semaphore object.
+
+- The Multiprocessor Resource Sharing Protocol needs a ceiling priority per
+ scheduler instance. This operation can be used to specify these priority
+ values.
+
+- For the Priority Ceiling Protocol the ceiling priority is used with this
+ operation.
+
+- For other protocols this operation is not defined.
+
+**EXAMPLE:**
+
+.. code:: c
+
+ #include <assert.h>
+ #include <stdlib.h>
+ #include <rtems.h>
+ #define SCHED_A rtems_build_name(' ', ' ', ' ', 'A')
+ #define SCHED_B rtems_build_name(' ', ' ', ' ', 'B')
+ static void Init(rtems_task_argument arg)
+ {
+ rtems_status_code sc;
+ rtems_id semaphore_id;
+ rtems_id scheduler_a_id;
+ rtems_id scheduler_b_id;
+ rtems_task_priority prio;
+ /* Get the scheduler identifiers \*/
+ sc = rtems_scheduler_ident(SCHED_A, &scheduler_a_id);
+ assert(sc == RTEMS_SUCCESSFUL);
+ sc = rtems_scheduler_ident(SCHED_B, &scheduler_b_id);
+ assert(sc == RTEMS_SUCCESSFUL);
+ /* Create a MrsP semaphore object \*/
+ sc = rtems_semaphore_create(
+ rtems_build_name('M', 'R', 'S', 'P'),
+ 1,
+ RTEMS_MULTIPROCESSOR_RESOURCE_SHARING
+ | RTEMS_BINARY_SEMAPHORE,
+ 1,
+ &semaphore_id
+ );
+ assert(sc == RTEMS_SUCCESSFUL);
+ /*
+ * The ceiling priority values per scheduler are equal to the value specified
+ * for object creation.
+ \*/
+ prio = RTEMS_CURRENT_PRIORITY;
+ sc = rtems_semaphore_set_priority(semaphore_id, scheduler_a_id, prio, &prio);
+ assert(sc == RTEMS_SUCCESSFUL);
+ assert(prio == 1);
+ /* Check the old value and set a new ceiling priority for scheduler B \*/
+ prio = 2;
+ sc = rtems_semaphore_set_priority(semaphore_id, scheduler_b_id, prio, &prio);
+ assert(sc == RTEMS_SUCCESSFUL);
+ assert(prio == 1);
+ /* Check the ceiling priority values \*/
+ prio = RTEMS_CURRENT_PRIORITY;
+ sc = rtems_semaphore_set_priority(semaphore_id, scheduler_a_id, prio, &prio);
+ assert(sc == RTEMS_SUCCESSFUL);
+ assert(prio == 1);
+ prio = RTEMS_CURRENT_PRIORITY;
+ sc = rtems_semaphore_set_priority(semaphore_id, scheduler_b_id, prio, &prio);
+ assert(sc == RTEMS_SUCCESSFUL);
+ assert(prio == 2);
+ sc = rtems_semaphore_delete(semaphore_id);
+ assert(sc == RTEMS_SUCCESSFUL);
+ exit(0);
+ }
+ #define CONFIGURE_SMP_APPLICATION
+ #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+ #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+ #define CONFIGURE_MAXIMUM_TASKS 1
+ #define CONFIGURE_MAXIMUM_SEMAPHORES 1
+ #define CONFIGURE_MAXIMUM_MRSP_SEMAPHORES 1
+ #define CONFIGURE_SMP_MAXIMUM_PROCESSORS 2
+ #define CONFIGURE_SCHEDULER_SIMPLE_SMP
+ #include <rtems/scheduler.h>
+ RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(a);
+ RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(b);
+ #define CONFIGURE_SCHEDULER_CONTROLS \\
+ RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(a, SCHED_A), \\
+ RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(b, SCHED_B)
+ #define CONFIGURE_SMP_SCHEDULER_ASSIGNMENTS \\
+ RTEMS_SCHEDULER_ASSIGN(0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY), \\
+ RTEMS_SCHEDULER_ASSIGN(1, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY)
+ #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+ #define CONFIGURE_INIT
+ #include <rtems/confdefs.h>
+
+.. COMMENT: COPYRIGHT (c) 1988-2007.
+
+.. COMMENT: On-Line Applications Research Corporation (OAR).
+
+.. COMMENT: All rights reserved.
+