From fd6dc8c8de4dbc7ecf8a82a597cd5b43476fc8e3 Mon Sep 17 00:00:00 2001 From: Amar Takhar Date: Sun, 17 Jan 2016 19:19:43 -0500 Subject: Split document into seperate files by section. --- c_user/semaphore_manager.rst | 926 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 926 insertions(+) create mode 100644 c_user/semaphore_manager.rst (limited to 'c_user/semaphore_manager.rst') 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 + #include + #include + #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_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 + +.. COMMENT: COPYRIGHT (c) 1988-2007. + +.. COMMENT: On-Line Applications Research Corporation (OAR). + +.. COMMENT: All rights reserved. + -- cgit v1.2.3