diff --git a/c-user/semaphore/directives.rst b/c-user/semaphore/directives.rst index 460947d..28b639d 100644 --- a/c-user/semaphore/directives.rst +++ b/c-user/semaphore/directives.rst @@ -1,650 +1,1015 @@ .. SPDX-License-Identifier: CC-BY-SA-4.0 +.. Copyright (C) 2020, 2021 embedded brains GmbH (http://www.embedded-brains.de) .. Copyright (C) 1988, 2008 On-Line Applications Research Corporation (OAR) +.. This file is part of the RTEMS quality process and was automatically +.. generated. If you find something that needs to be fixed or +.. worded better please post a report or patch to an RTEMS mailing list +.. or raise a bug report: +.. +.. https://www.rtems.org/bugs.html +.. +.. For information on updating and regenerating please refer to the How-To +.. section in the Software Requirements Engineering chapter of the +.. RTEMS Software Engineering manual. The manual is provided as a part of +.. a release. For development sources please refer to the online +.. documentation at: +.. +.. https://docs.rtems.org + +.. _SemaphoreManagerDirectives: + 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. +This section details the directives of the Semaphore Manager. A subsection is +dedicated to each of this manager's directives and lists the calling sequence, +parameters, description, return values, and notes of the directive. + +.. Generated from spec:/rtems/sem/if/create .. raw:: latex - \clearpage + \clearpage +.. index:: rtems_semaphore_create() .. index:: create a semaphore -.. index:: rtems_semaphore_create -.. _rtems_semaphore_create: +.. _InterfaceRtemsSemaphoreCreate: -SEMAPHORE_CREATE - Create a semaphore -------------------------------------- +rtems_semaphore_create() +------------------------ +Creates a semaphore. -CALLING SEQUENCE: - .. code-block:: c +.. rubric:: CALLING SEQUENCE: - rtems_status_code rtems_semaphore_create( - rtems_name name, - uint32_t count, - rtems_attribute attribute_set, - rtems_task_priority priority_ceiling, - rtems_id *id - ); +.. code-block:: c -DIRECTIVE STATUS CODES: - .. list-table:: - :class: rtems-table + rtems_status_code rtems_semaphore_create( + rtems_name name, + uint32_t count, + rtems_attribute attribute_set, + rtems_task_priority priority_ceiling, + rtems_id *id + ); - * - ``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_TOO_MANY`` - - too many global objects +.. rubric:: PARAMETERS: -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. +``name`` + This parameter is the object name of 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. +``count`` + This parameter is the initial count of the semaphore. If the semaphore is + a binary semaphore, then a count of 0 will make the calling task the owner + of the binary semaphore and a count of 1 will create a binary semaphore + without an owner. -NOTES: - This directive may cause the calling task to be preempted due to an - obtain and release of the object allocator mutex. +``attribute_set`` + This parameter is the attribute set of the semaphore. - The priority inheritance and priority ceiling algorithms are only supported - for local, binary semaphores that use the priority task wait queue blocking - discipline. +``priority_ceiling`` + This parameter is the priority ceiling if the semaphore is a binary + semaphore with the priority ceiling or MrsP locking protocol as defined by + the attribute set. - The following semaphore attribute constants are defined by RTEMS: +``id`` + This parameter is the pointer to an object identifier variable. When the + directive call is successful, the identifier of the created semaphore will + be stored in this variable. - .. list-table:: - :class: rtems-table +.. rubric:: DESCRIPTION: - * - ``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 +This directive creates a semaphore which resides on the local node. The +semaphore has the user-defined object name specified in ``name`` and the +initial count specified in ``count``. The assigned object identifier is +returned in ``id``. This identifier is used to access the semaphore with other +semaphore related directives. - 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. +The **attribute set** specified in ``attribute_set`` is built through a +*bitwise or* of the attribute constants described below. Not all combinations +of attributes are allowed. Some attributes are mutually exclusive. If +mutually exclusive attributes are combined, the behaviour is undefined. +Attributes not mentioned below are not evaluated by this directive and have no +effect. Default attributes can be selected by using the +:c:macro:`RTEMS_DEFAULT_ATTRIBUTES` constant. The attribute set defines - *Note*, some combinations of attributes are not valid. See the earlier - discussion on this. +* the scope of the semaphore: :c:macro:`RTEMS_LOCAL` (default) or + :c:macro:`RTEMS_GLOBAL`, - The total number of global objects, including semaphores, is limited by the - maximum_global_objects field in the Configuration Table. +* the task wait queue discipline used by the semaphore: :c:macro:`RTEMS_FIFO` + (default) or :c:macro:`RTEMS_PRIORITY`, - It is not allowed to create an initially locked MrsP semaphore and the - ``RTEMS_INVALID_NUMBER`` status code will be returned in SMP configurations - in this case. This prevents lock order reversal problems with the - allocator mutex. +* the class of the semaphore: :c:macro:`RTEMS_COUNTING_SEMAPHORE` (default), + :c:macro:`RTEMS_BINARY_SEMAPHORE`, or + :c:macro:`RTEMS_SIMPLE_BINARY_SEMAPHORE`, and + +* the locking protocol of a binary semaphore: no locking protocol (default), + :c:macro:`RTEMS_INHERIT_PRIORITY`, :c:macro:`RTEMS_PRIORITY_CEILING`, or + :c:macro:`RTEMS_MULTIPROCESSOR_RESOURCE_SHARING`. + +The semaphore has a local or global **scope** in a multiprocessing network +(this attribute does not refer to SMP systems). The scope is selected by the +mutually exclusive :c:macro:`RTEMS_LOCAL` and :c:macro:`RTEMS_GLOBAL` +attributes. + +* A **local scope** is the default and can be emphasized through the use of the + :c:macro:`RTEMS_LOCAL` attribute. A local semaphore can be only used by the + node which created it. + +* A **global scope** is established if the :c:macro:`RTEMS_GLOBAL` attribute is + set. Setting the global attribute in a single node system has no effect. + +The **task wait queue discipline** is selected by the mutually exclusive +:c:macro:`RTEMS_FIFO` and :c:macro:`RTEMS_PRIORITY` attributes. + +* The **FIFO discipline** is the default and can be emphasized through use of + the :c:macro:`RTEMS_FIFO` attribute. + +* The **priority discipline** is selected by the :c:macro:`RTEMS_PRIORITY` + attribute. The locking protocols require the priority discipline. + +The **semaphore class** is selected by the mutually exclusive +:c:macro:`RTEMS_COUNTING_SEMAPHORE`, :c:macro:`RTEMS_BINARY_SEMAPHORE`, and +:c:macro:`RTEMS_SIMPLE_BINARY_SEMAPHORE` attributes. + +* The **counting semaphore class** is the default and can be emphasized through + use of the :c:macro:`RTEMS_COUNTING_SEMAPHORE` attribute. + +* The **binary semaphore class** is selected by the + :c:macro:`RTEMS_BINARY_SEMAPHORE` attribute. Binary semaphores are mutual + exclusion (mutex) synchronization primitives which may have an owner. The + count of a binary semaphore is restricted to 0 and 1 values. + +* The **simple binary semaphore class** is selected by the + :c:macro:`RTEMS_SIMPLE_BINARY_SEMAPHORE` attribute. Simple binary semaphores + have no owner. They may be used for task and interrupt synchronization. The + count of a simple binary semaphore is restricted to 0 and 1 values. + +Binary semaphores may use a **locking protocol**. If a locking protocol is +selected, then the scope shall be local and the priority task wait queue +discipline shall be selected. The locking protocol is selected by the mutually +exclusive :c:macro:`RTEMS_INHERIT_PRIORITY`, :c:macro:`RTEMS_PRIORITY_CEILING`, +and :c:macro:`RTEMS_MULTIPROCESSOR_RESOURCE_SHARING` attributes. + +* The default is **no locking protocol**. This can be emphasized through use + of the :c:macro:`RTEMS_NO_INHERIT_PRIORITY`, + :c:macro:`RTEMS_NO_MULTIPROCESSOR_RESOURCE_SHARING`, and + :c:macro:`RTEMS_NO_PRIORITY_CEILING` attributes. + +* The **priority inheritance locking protocol** is selected by the + :c:macro:`RTEMS_INHERIT_PRIORITY` attribute. + +* The **priority ceiling locking protocol** is selected by the + :c:macro:`RTEMS_PRIORITY_CEILING` attribute. For this locking protocol a + priority ceiling shall be specified in ``priority_ceiling``. + +* The **MrsP locking protocol** is selected by the + :c:macro:`RTEMS_MULTIPROCESSOR_RESOURCE_SHARING` attribute in SMP + configurations, otherwise this attribute selects the **priority ceiling + locking protocol**. For these locking protocols a priority ceiling shall be + specified in ``priority_ceiling``. This priority is used to set the priority + ceiling for all schedulers. This can be changed later with the + :ref:`InterfaceRtemsSemaphoreSetPriority` directive using the returned object + identifier. + +.. rubric:: RETURN VALUES: + +:c:macro:`RTEMS_SUCCESSFUL` + The requested operation was successful. + +:c:macro:`RTEMS_INVALID_NAME` + The ``name`` parameter was invalid. + +:c:macro:`RTEMS_INVALID_ADDRESS` + The ``id`` parameter was `NULL + `_. + +:c:macro:`RTEMS_INVALID_NUMBER` + The ``count`` parameter was invalid. + +:c:macro:`RTEMS_NOT_DEFINED` + The ``attribute_set`` parameter was invalid. + +:c:macro:`RTEMS_TOO_MANY` + There was no inactive object available to create a semaphore. The number + of semaphores available to the application is configured through the + :ref:`CONFIGURE_MAXIMUM_SEMAPHORES` application configuration option. + +:c:macro:`RTEMS_TOO_MANY` + In multiprocessing configurations, there was no inactive global object + available to create a global semaphore. The number of global objects + available to the application is configured through the + :ref:`CONFIGURE_MP_MAXIMUM_GLOBAL_OBJECTS` application configuration + option. + +:c:macro:`RTEMS_INVALID_PRIORITY` + The ``priority_ceiling`` parameter was invalid. + +.. rubric:: NOTES: + +For control and maintenance of the semaphore, RTEMS allocates a :term:`SMCB` +from the local SMCB free pool and initializes it. + +The SMCB for a global semaphore is allocated on the local node. Semaphores +should not be made global unless remote tasks must interact with the 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 +identifier must be transmitted to every node in the system for insertion in the +local copy of the global object table. + +.. rubric:: CONSTRAINTS: + +The following constraints apply to this directive: + +* The directive may be called from within device driver initialization context. + +* The directive may be called from within task context. + +* The directive may obtain and release the object allocator mutex. This may + cause the calling task to be preempted. + +* When the directive operates on a global object, the directive sends a message + to remote nodes. This may preempt the calling task. + +* When a semaphore using the MrsP locking protocol is created, the initial + count shall be exactly one. + +* The number of semaphores available to the application is configured through + the :ref:`CONFIGURE_MAXIMUM_SEMAPHORES` application configuration option. + +* Where the object class corresponding to the directive is configured to use + unlimited objects, the directive may allocate memory from the RTEMS + Workspace. + +* The number of global objects available to the application is configured + through the :ref:`CONFIGURE_MP_MAXIMUM_GLOBAL_OBJECTS` application + configuration option. + +.. Generated from spec:/rtems/sem/if/ident .. raw:: latex - \clearpage + \clearpage -.. index:: get ID of a semaphore -.. index:: obtain ID of a semaphore -.. index:: rtems_semaphore_ident +.. index:: rtems_semaphore_ident() -.. _rtems_semaphore_ident: +.. _InterfaceRtemsSemaphoreIdent: -SEMAPHORE_IDENT - Get ID of a semaphore ---------------------------------------- +rtems_semaphore_ident() +----------------------- -CALLING SEQUENCE: - .. code-block:: c +Identifies a semaphore by the object name. - rtems_status_code rtems_semaphore_ident( - rtems_name name, - uint32_t node, - rtems_id *id - ); +.. rubric:: CALLING SEQUENCE: -DIRECTIVE STATUS CODES: - .. list-table:: - :class: rtems-table +.. code-block:: c - * - ``RTEMS_SUCCESSFUL`` - - semaphore identified successfully - * - ``RTEMS_INVALID_NAME`` - - semaphore name not found - * - ``RTEMS_INVALID_NODE`` - - invalid node id + rtems_status_code rtems_semaphore_ident( + rtems_name name, + uint32_t node, + rtems_id *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. +.. rubric:: PARAMETERS: -NOTES: - This directive will not cause the running task to be preempted. +``name`` + This parameter is the object name to look up. - 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. +``node`` + This parameter is the node or node set to search for a matching object. - 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. +``id`` + This parameter is the pointer to an object identifier variable. When the + directive call is successful, the object identifier of an object with the + specified name will be stored in this variable. - This directive does not generate activity on remote nodes. It accesses - only the local copy of the global object table. +.. rubric:: DESCRIPTION: + +This directive obtains a semaphore identifier associated with the semaphore +name specified in ``name``. + +The node to search is specified in ``node``. It shall be + +* a valid node number, + +* the constant :c:macro:`RTEMS_SEARCH_ALL_NODES` to search in all nodes, + +* the constant :c:macro:`RTEMS_SEARCH_LOCAL_NODE` to search in the local node + only, or + +* the constant :c:macro:`RTEMS_SEARCH_OTHER_NODES` to search in all nodes + except the local node. + +.. rubric:: RETURN VALUES: + +:c:macro:`RTEMS_SUCCESSFUL` + The requested operation was successful. + +:c:macro:`RTEMS_INVALID_ADDRESS` + The ``id`` parameter was `NULL + `_. + +:c:macro:`RTEMS_INVALID_NAME` + The ``name`` parameter was 0. + +:c:macro:`RTEMS_INVALID_NAME` + There was no object with the specified name on the specified nodes. + +:c:macro:`RTEMS_INVALID_NODE` + In multiprocessing configurations, the specified node was invalid. + +.. rubric:: NOTES: + +If the semaphore name is not unique, then the semaphore identifier will match +the first semaphore with that name in the search order. However, this +semaphore identifier is not guaranteed to correspond to the desired semaphore. + +The objects are searched from lowest to the highest index. If ``node`` is +:c:macro:`RTEMS_SEARCH_ALL_NODES`, all nodes are searched with the local node +being searched first. All other nodes are searched from lowest to the highest +node number. + +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. + +The semaphore identifier is used with other semaphore related directives to +access the semaphore. + +.. rubric:: CONSTRAINTS: + +The following constraints apply to this directive: + +* The directive may be called from within any runtime context. + +* The directive will not cause the calling task to be preempted. + +.. Generated from spec:/rtems/sem/if/delete .. raw:: latex - \clearpage + \clearpage +.. index:: rtems_semaphore_delete() .. index:: delete a semaphore -.. index:: rtems_semaphore_delete -.. _rtems_semaphore_delete: +.. _InterfaceRtemsSemaphoreDelete: -SEMAPHORE_DELETE - Delete a semaphore -------------------------------------- +rtems_semaphore_delete() +------------------------ -CALLING SEQUENCE: - .. code-block:: c +Deletes the semaphore. - rtems_status_code rtems_semaphore_delete( - rtems_id id - ); +.. rubric:: CALLING SEQUENCE: -DIRECTIVE STATUS CODES: - .. list-table:: - :class: rtems-table +.. code-block:: c - * - ``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 + rtems_status_code rtems_semaphore_delete( rtems_id id ); -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. +.. rubric:: PARAMETERS: -NOTES: - This directive may cause the calling task to be preempted due to an - obtain and release of the object allocator mutex. +``id`` + This parameter is the semaphore identifier. - 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. +.. rubric:: DESCRIPTION: - 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. +This directive deletes the semaphore specified by ``id``. - 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. +.. rubric:: RETURN VALUES: - The semaphore must reside on the local node, even if the semaphore was - created with the ``RTEMS_GLOBAL`` option. +:c:macro:`RTEMS_SUCCESSFUL` + The requested operation was successful. - Proxies, used to represent remote tasks, are reclaimed when the semaphore - is deleted. +:c:macro:`RTEMS_INVALID_ID` + There was no semaphore associated with the identifier specified by ``id``. + +:c:macro:`RTEMS_ILLEGAL_ON_REMOTE_OBJECT` + The semaphore resided on a remote node. + +:c:macro:`RTEMS_RESOURCE_IN_USE` + The binary semaphore had an owner. + +.. rubric:: NOTES: + +Binary semaphores with an owner cannot be deleted. + +When a semaphore is deleted, all tasks blocked waiting to obtain the semaphore +will be readied and returned a status code which indicates that the semaphore +was deleted. + +The :term:`SMCB` for the deleted semaphore is reclaimed by RTEMS. + +When a global semaphore is deleted, the semaphore identifier 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 :c:macro:`RTEMS_GLOBAL` attribute. + +Proxies, used to represent remote tasks, are reclaimed when the semaphore is +deleted. + +.. rubric:: CONSTRAINTS: + +The following constraints apply to this directive: + +* The directive may be called from within device driver initialization context. + +* The directive may be called from within task context. + +* The directive may obtain and release the object allocator mutex. This may + cause the calling task to be preempted. + +* When the directive operates on a global object, the directive sends a message + to remote nodes. This may preempt the calling task. + +* The calling task does not have to be the task that created the object. Any + local task that knows the object identifier can delete the object. + +* Where the object class corresponding to the directive is configured to use + unlimited objects, the directive may free memory to the RTEMS Workspace. + +.. Generated from spec:/rtems/sem/if/obtain .. raw:: latex - \clearpage + \clearpage +.. index:: rtems_semaphore_obtain() .. index:: obtain a semaphore .. index:: lock a semaphore -.. index:: rtems_semaphore_obtain -.. _rtems_semaphore_obtain: +.. _InterfaceRtemsSemaphoreObtain: -SEMAPHORE_OBTAIN - Acquire a semaphore --------------------------------------- +rtems_semaphore_obtain() +------------------------ -CALLING SEQUENCE: - .. code-block:: c +Obtains the semaphore. - rtems_status_code rtems_semaphore_obtain( - rtems_id id, - rtems_option option_set, - rtems_interval timeout - ); +.. rubric:: CALLING SEQUENCE: -DIRECTIVE STATUS CODES: - .. list-table:: - :class: rtems-table +.. code-block:: c - * - ``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 + rtems_status_code rtems_semaphore_obtain( + rtems_id id, + rtems_option option_set, + rtems_interval timeout + ); -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. +.. rubric:: PARAMETERS: - 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. +``id`` + This parameter is the semaphore identifier. - 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. +``option_set`` + This parameter is the option set. - In case a semaphore is not available, then ``RTEMS_UNSATISFIED`` will be - returned. This happens immediately in case ``RTEMS_NO_WAIT`` is specified, - or as a result of another task invoking the ``rtems_semaphore_flush`` - directive in case ``RTEMS_WAIT`` is specified. +``timeout`` + This parameter is the timeout in clock ticks if the :c:macro:`RTEMS_WAIT` + option is set. Use :c:macro:`RTEMS_NO_TIMEOUT` to wait potentially + forever. - Deadlock situations are detected for MrsP semaphores and the - ``RTEMS_UNSATISFIED`` status code will be returned in SMP configurations in - this case. +.. rubric:: DESCRIPTION: -NOTES: - The following semaphore acquisition option constants are defined by RTEMS: +This directive obtains the semaphore specified by ``id``. - .. list-table:: - :class: rtems-table +The **option set** specified in ``option_set`` is built through a *bitwise or* +of the option constants described below. Not all combinations of options are +allowed. Some options are mutually exclusive. If mutually exclusive options +are combined, the behaviour is undefined. Options not mentioned below are not +evaluated by this directive and have no effect. Default options can be selected +by using the :c:macro:`RTEMS_DEFAULT_OPTIONS` constant. - * - ``RTEMS_WAIT`` - - task will wait for semaphore (default) - * - ``RTEMS_NO_WAIT`` - - task should not wait +The calling task can **wait** or **try to obtain** the semaphore according to +the mutually exclusive :c:macro:`RTEMS_WAIT` and :c:macro:`RTEMS_NO_WAIT` +options. - 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. +* **Waiting to obtain** the semaphore is the default and can be emphasized + through the use of the :c:macro:`RTEMS_WAIT` option. The ``timeout`` + parameter defines how long the calling task is willing to wait. Use + :c:macro:`RTEMS_NO_TIMEOUT` to wait potentially forever, otherwise set a + timeout interval in clock ticks. - A clock tick is required to support the timeout functionality of this - directive. +* **Trying to obtain** the semaphore is selected by the + :c:macro:`RTEMS_NO_WAIT` option. If this option is defined, then the + ``timeout`` parameter is ignored. When the semaphore cannot be immediately + obtained, then the :c:macro:`RTEMS_UNSATISFIED` status is returned. - 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 in SMP configurations in this case. +With either :c:macro:`RTEMS_WAIT` or :c:macro:`RTEMS_NO_WAIT` if the current +semaphore count is positive, then it is decremented by one and the semaphore is +successfully obtained by returning immediately with the +:c:macro:`RTEMS_SUCCESSFUL` status code. + +If the calling task chooses to return immediately and the current semaphore +count is zero, then the :c:macro:`RTEMS_UNSATISFIED` 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, then the calling task is placed on the semaphore's wait queue +and blocked. If a local, binary semaphore was created with the +:c:macro:`RTEMS_INHERIT_PRIORITY` attribute, then the priority of the task +currently holding the binary semaphore will inherit the current priority set of +the blocking task. The priority inheritance is carried out recursively. This +means, that if the task currently holding the binary semaphore is blocked on +another local, binary semaphore using the priority inheritance locking +protocol, then the owner of this semaphore will inherit the current priority +sets of both tasks, and so on. A task has a current priority for each +scheduler. + +.. rubric:: RETURN VALUES: + +:c:macro:`RTEMS_SUCCESSFUL` + The requested operation was successful. + +:c:macro:`RTEMS_INVALID_ID` + There was no semaphore associated with the identifier specified by ``id``. + +:c:macro:`RTEMS_UNSATISFIED` + The semaphore could not be obtained immediately. + +:c:macro:`RTEMS_INCORRECT_STATE` + Acquiring of the local, binary semaphore by the calling task would have + cased a deadlock. + +:c:macro:`RTEMS_INCORRECT_STATE` + The calling task attempted to recursively obtain a local, binary semaphore + using the MrsP locking protocol. + +:c:macro:`RTEMS_UNSATISFIED` + The semaphore was flushed while the calling task was waiting to obtain the + semaphore. + +:c:macro:`RTEMS_TIMEOUT` + The timeout happened while the calling task was waiting to obtain the + semaphore. + +:c:macro:`RTEMS_OBJECT_WAS_DELETED` + The semaphore was deleted while the calling task was waiting to obtain the + semaphore. + +.. rubric:: NOTES: + +If a local, binary semaphore was created with the +:c:macro:`RTEMS_PRIORITY_CEILING` or +:c:macro:`RTEMS_MULTIPROCESSOR_RESOURCE_SHARING` 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 acquiring +the semaphore is elevated to that of the ceiling. + +Deadlock situations are detected for local, binary semaphores. If a deadlock +is detected, then the directive immediately returns the +:c:macro:`RTEMS_INCORRECT_STATE` status code. + +It is not allowed to recursively obtain (nested access) a local, binary +semaphore using the MrsP locking protocol and any attempt to do this will just +return the :c:macro:`RTEMS_INCORRECT_STATE` status code. This error can only +happen in SMP configurations. + +If the semaphore was created with the :c:macro:`RTEMS_PRIORITY` attribute, then +the calling task is inserted into the wait queue according to its priority. +However, if the semaphore was created with the :c:macro:`RTEMS_FIFO` attribute, +then the calling task is placed at the rear of the wait queue. + +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 :c:macro:`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. + +.. rubric:: CONSTRAINTS: + +The following constraints apply to this directive: + +* When a local, counting semaphore or a local, simple binary semaphore is + accessed and the :c:macro:`RTEMS_NO_WAIT` option is set, the directive may be + called from within interrupt context. + +* When a local semaphore is accessed and the request can be immediately + satisfied, the directive may be called from within device driver + initialization context. + +* The directive may be called from within task context. + +* When the request cannot be immediately satisfied and the + :c:macro:`RTEMS_WAIT` option is set, the calling task blocks at some point + during the directive call. + +* The timeout functionality of the directive requires a :term:`clock tick`. + +* When the directive operates on a remote object, the directive sends a message + to the remote node and waits for a reply. This will preempt the calling + task. + +.. Generated from spec:/rtems/sem/if/release .. raw:: latex - \clearpage + \clearpage +.. index:: rtems_semaphore_release() .. index:: release a semaphore .. index:: unlock a semaphore -.. index:: rtems_semaphore_release -.. _rtems_semaphore_release: +.. _InterfaceRtemsSemaphoreRelease: -SEMAPHORE_RELEASE - Release a semaphore ---------------------------------------- +rtems_semaphore_release() +------------------------- -CALLING SEQUENCE: - .. code-block:: c +Releases the semaphore. - rtems_status_code rtems_semaphore_release( - rtems_id id - ); +.. rubric:: CALLING SEQUENCE: -DIRECTIVE STATUS CODES: - .. list-table:: - :class: rtems-table +.. code-block:: c - * - ``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 + rtems_status_code rtems_semaphore_release( rtems_id id ); -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. +.. rubric:: PARAMETERS: -NOTES: - The calling task may be preempted if it causes a higher priority task to be - made ready for execution. +``id`` + This parameter is the semaphore identifier. - Releasing a global semaphore which does not reside on the local node will - generate a request telling the remote node to release the semaphore. +.. rubric:: DESCRIPTION: - 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. +This directive releases the semaphore specified by ``id``. If the semaphore's +wait queue is not empty, then - 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 first task on the wait queue is removed and unblocked, the semaphore's + count is not changed, otherwise - The MrsP semaphores must be released in the reversed obtain order, - otherwise the ``RTEMS_INCORRECT_STATE`` status code will be returned in SMP - configurations in this case. +* the semaphore's count is incremented by one for counting semaphores and set + to one for binary and simple binary semaphores. + +.. rubric:: RETURN VALUES: + +:c:macro:`RTEMS_SUCCESSFUL` + The requested operation was successful. + +:c:macro:`RTEMS_INVALID_ID` + There was no semaphore associated with the identifier specified by ``id``. + +:c:macro:`RTEMS_NOT_OWNER_OF_RESOURCE` + The calling task was not the owner of the semaphore. + +:c:macro:`RTEMS_INTERNAL_ERROR` + The semaphore's count already had the maximum value of `UINT32_MAX + `_. + +.. rubric:: NOTES: + +The calling task may be preempted if it causes a higher priority task to be +made ready for execution. + +The outermost release of a local, binary semaphore using the priority +inheritance, priority ceiling, or MrsP locking protocol may result in the +calling task having its priority lowered. This will occur if the highest +priority of the calling task was available due to the ownership of the released +semaphore. If a task was on the semaphore's wait queue, then the priority +associated with the semaphore will be transferred to the new owner. + +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. + +.. rubric:: CONSTRAINTS: + +The following constraints apply to this directive: + +* When a local, counting semaphore or a local, simple binary semaphore is + accessed, the directive may be called from within interrupt context. + +* When a local semaphore is accessed, the directive may be called from within + device driver initialization context. + +* The directive may be called from within task context. + +* The directive may unblock another task which may preempt the calling task. + +* When the directive operates on a remote object, the directive sends a message + to the remote node and waits for a reply. This will preempt the calling + task. + +.. Generated from spec:/rtems/sem/if/flush .. raw:: latex - \clearpage + \clearpage +.. index:: rtems_semaphore_flush() .. index:: flush a semaphore .. index:: unblock all tasks waiting on a semaphore -.. index:: rtems_semaphore_flush -.. _rtems_semaphore_flush: +.. _InterfaceRtemsSemaphoreFlush: -SEMAPHORE_FLUSH - Unblock all tasks waiting on a semaphore ----------------------------------------------------------- +rtems_semaphore_flush() +----------------------- -CALLING SEQUENCE: - .. code-block:: c +Flushes the semaphore. - rtems_status_code rtems_semaphore_flush( - rtems_id id - ); +.. rubric:: CALLING SEQUENCE: -DIRECTIVE STATUS CODES: - .. list-table:: - :class: rtems-table +.. code-block:: c - * - ``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 + rtems_status_code rtems_semaphore_flush( rtems_id id ); -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. +.. rubric:: PARAMETERS: - 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. +``id`` + This parameter is the semaphore identifier. -NOTES: - The calling task may be preempted if it causes a higher priority task to be - made ready for execution. +.. rubric:: DESCRIPTION: - 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. +This directive unblocks all tasks waiting on the semaphore specified by ``id``. +The semaphore's count is not changed by this directive. Tasks which are +unblocked as the result of this directive will return from the +:ref:`InterfaceRtemsSemaphoreObtain` directive with a status code of +:c:macro:`RTEMS_UNSATISFIED` to indicate that the semaphore was not obtained. - It is not allowed to flush a MrsP semaphore and the ``RTEMS_NOT_DEFINED`` - status code will be returned in SMP configurations in this case. +.. rubric:: RETURN VALUES: - Using the ``rtems_semaphore_flush`` directive for condition synchronization - in concert with another semaphore may be subject to the lost wake-up - problem. The following attempt to implement a condition variable is - broken. +:c:macro:`RTEMS_SUCCESSFUL` + The requested operation was successful. - .. code-block:: c +:c:macro:`RTEMS_INVALID_ID` + There was no semaphore associated with the identifier specified by ``id``. - #include - #include +:c:macro:`RTEMS_ILLEGAL_ON_REMOTE_OBJECT` + The semaphore resided on a remote node. - void cnd_wait( rtems_id cnd, rtems_id mtx ) - { - rtems_status_code sc; +:c:macro:`RTEMS_NOT_DEFINED` + Flushing a semaphore using the MrsP locking protocol is undefined + behaviour. - sc = rtems_semaphore_release( mtx ); - assert( sc == RTEMS_SUCCESSFUL ); +.. rubric:: NOTES: - /* - * Here, a higher priority task may run and satisfy the condition. We - * may never wake up from the next semaphore obtain. - */ +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. - sc = rtems_semaphore_obtain( cnd, RTEMS_WAIT, RTEMS_NO_TIMEOUT ); - assert( sc == RTEMS_UNSATISFIED ); +It is not allowed to flush a local, binary semaphore using the MrsP locking +protocol and any attempt to do this will just return the +:c:macro:`RTEMS_NOT_DEFINED` status code. This error can only happen in SMP +configurations. - sc = rtems_semaphore_obtain( mtx, RTEMS_WAIT, RTEMS_NO_TIMEOUT ); - assert( sc == RTEMS_SUCCESSFUL ); - } +For barrier synchronization, the :ref:`RTEMSAPIClassicBarrier` offers a cleaner +alternative to using the semaphore flush directive. Unlike POSIX barriers, +they have a manual release option. - void cnd_broadcast( rtems_id cnd ) - { - rtems_status_code sc; +Using the semaphore flush directive for condition synchronization in concert +with another semaphore may be subject to the lost wake-up problem. The +following attempt to implement a condition variable is broken. - sc = rtems_semaphore_flush( cnd ); - assert( sc == RTEMS_SUCCESSFUL ); - } +.. code-block:: c + :linenos: - For barrier synchronization, the :ref:`barrier_manager` offers a cleaner - alternative to using the `rtems_semaphore_flush` directive. Unlike POSIX - barriers, they have a manual release option. + #include + #include + + void cnd_wait( rtems_id cnd, rtems_id mtx ) + { + rtems_status_code sc; + + sc = rtems_semaphore_release( mtx ); + assert( sc == RTEMS_SUCCESSFUL ); + + // Here, a higher priority task may run and satisfy the condition. + // We may never wake up from the next semaphore obtain. + + sc = rtems_semaphore_obtain( cnd, RTEMS_WAIT, RTEMS_NO_TIMEOUT ); + assert( sc == RTEMS_UNSATISFIED ); + + sc = rtems_semaphore_obtain( mtx, RTEMS_WAIT, RTEMS_NO_TIMEOUT ); + assert( sc == RTEMS_SUCCESSFUL ); + } + + void cnd_broadcast( rtems_id cnd ) + { + rtems_status_code sc; + + sc = rtems_semaphore_flush( cnd ); + assert( sc == RTEMS_SUCCESSFUL ); + } + +.. rubric:: CONSTRAINTS: + +The following constraints apply to this directive: + +* When a local, counting semaphore or a local, simple binary semaphore is + accessed, the directive may be called from within interrupt context. + +* When a local semaphore is accessed, the directive may be called from within + device driver initialization context. + +* The directive may be called from within task context. + +* The directive may unblock another task which may preempt the calling task. + +* When the directive operates on a remote object, the directive sends a message + to the remote node and waits for a reply. This will preempt the calling + task. + +.. Generated from spec:/rtems/sem/if/set-priority .. raw:: latex - \clearpage + \clearpage +.. index:: rtems_semaphore_set_priority() .. index:: set priority by scheduler for a semaphore -.. index:: rtems_semaphore_set_priority -.. _rtems_semaphore_set_priority: +.. _InterfaceRtemsSemaphoreSetPriority: -SEMAPHORE_SET_PRIORITY - Set priority by scheduler for a semaphore ------------------------------------------------------------------- +rtems_semaphore_set_priority() +------------------------------ -CALLING SEQUENCE: - .. code-block:: c +Sets the priority by scheduler for the semaphore. - 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 - ); +.. rubric:: CALLING SEQUENCE: -DIRECTIVE STATUS CODES: - .. list-table:: - :class: rtems-table +.. code-block:: c - * - ``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 ofthe semaphore - * - ``RTEMS_ILLEGAL_ON_REMOTE_OBJECT`` - - not supported for remote semaphores + 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 + ); -DESCRIPTION: - This directive sets the priority value with respect to the specified - scheduler of a semaphore. +.. rubric:: PARAMETERS: - The special priority value ``RTEMS_CURRENT_PRIORITY`` can be used to get - the current priority value without changing it. +``semaphore_id`` + This parameter is the semaphore identifier. - The interpretation of the priority value depends on the protocol of the - semaphore object. +``scheduler_id`` + This parameter is the identifier of the scheduler corresponding to the new + priority. - - The Multiprocessor Resource Sharing Protocol needs a ceiling priority per - scheduler instance. This operation can be used to specify these priority - values. +``new_priority`` + This parameter is the new priority corresponding to the specified + scheduler. - - For the Priority Ceiling Protocol the ceiling priority is used with this - operation. +``old_priority`` + This parameter is the pointer to a task priority variable. When the + directive call is successful, the old priority of the semaphore + corresponding to the specified scheduler will be stored in this variable. - - For other protocols this operation is not defined. +.. rubric:: DESCRIPTION: -EXAMPLE: - .. code-block:: c - :linenos: +This directive sets the priority of the semaphore specified by +``semaphore_id``. The priority corresponds to the scheduler specified by +``scheduler_id``. - #include - #include - #include +The special priority value :c:macro:`RTEMS_CURRENT_PRIORITY` can be used to get +the current priority without changing it. - #define SCHED_A rtems_build_name(' ', ' ', ' ', 'A') - #define SCHED_B rtems_build_name(' ', ' ', ' ', 'B') +The availability and use of a priority depends on the class and locking +protocol of the semaphore: - 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; +* For local, binary semaphores using the MrsP locking protocol, the ceiling + priority for each scheduler can be set by this directive. - /* 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); +* For local, binary semaphores using the priority ceiling protocol, the ceiling + priority can be set by this directive. - /* 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); +* For other semaphore classes and locking protocols, setting a priority is + undefined behaviour. - /* - * 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); +.. rubric:: RETURN VALUES: - /* 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); +:c:macro:`RTEMS_SUCCESSFUL` + The requested operation was successful. - /* 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); +:c:macro:`RTEMS_INVALID_ADDRESS` + The ``old_priority`` parameter was `NULL + `_. - sc = rtems_semaphore_delete(semaphore_id); - assert(sc == RTEMS_SUCCESSFUL); +:c:macro:`RTEMS_INVALID_ID` + There was no scheduler associated with the identifier specified by + ``scheduler_id``. - exit(0); - } +:c:macro:`RTEMS_INVALID_ID` + There was no semaphore associated with the identifier specified by + ``semaphore_id``. - #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_PROCESSORS 2 +:c:macro:`RTEMS_ILLEGAL_ON_REMOTE_OBJECT` + The semaphore resided on a remote node. - #define CONFIGURE_SCHEDULER_SIMPLE_SMP +:c:macro:`RTEMS_INVALID_PRIORITY` + The ``new_priority`` parameter was invalid. - #include +:c:macro:`RTEMS_NOT_DEFINED` + Setting a priority for the class or locking protocol of the semaphore is + undefined behaviour. - RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(a); - RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(b); +.. rubric:: NOTES: - #define CONFIGURE_SCHEDULER_TABLE_ENTRIES \ - RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(a, SCHED_A), \ - RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(b, SCHED_B) +Please have a look at the following example: - #define CONFIGURE_SCHEDULER_ASSIGNMENTS \ - RTEMS_SCHEDULER_ASSIGN(0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY), \ - RTEMS_SCHEDULER_ASSIGN(1, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY) +.. code-block:: c + :linenos: - #define CONFIGURE_RTEMS_INIT_TASKS_TABLE - #define CONFIGURE_INIT + #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; + + (void) arg; + + // 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 local, binary semaphore using the MrsP locking protocol + sc = rtems_semaphore_create( + rtems_build_name( 'M', 'R', 'S', 'P' ), + 1, + RTEMS_BINARY_SEMAPHORE | RTEMS_MULTIPROCESSOR_RESOURCE_SHARING, + 1, + &semaphore_id + ); + assert( sc == RTEMS_SUCCESSFUL ); + + // The ceiling priority for each scheduler is equal to the priority + // specified for the semaphore 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 ); + + rtems_shutdown_executive( 0 ); + } + + #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_PROCESSORS 2 + + #define CONFIGURE_SCHEDULER_SIMPLE_SMP + + #include + + RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP( a ); + RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP( b ); + + #define CONFIGURE_SCHEDULER_TABLE_ENTRIES \ + RTEMS_SCHEDULER_TABLE_SIMPLE_SMP( a, SCHED_A ), \ + RTEMS_SCHEDULER_TABLE_SIMPLE_SMP( b, SCHED_B ) + + #define CONFIGURE_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 + +.. rubric:: CONSTRAINTS: + +The following constraints apply to this directive: + +* The directive may be called from within interrupt context. + +* The directive may be called from within device driver initialization context. + +* The directive may be called from within task context. + +* The directive may change the priority of another task which may preempt the + calling task. diff --git a/c-user/semaphore/introduction.rst b/c-user/semaphore/introduction.rst index dee298b..9c36834 100644 --- a/c-user/semaphore/introduction.rst +++ b/c-user/semaphore/introduction.rst @@ -1,25 +1,55 @@ .. SPDX-License-Identifier: CC-BY-SA-4.0 +.. Copyright (C) 2020, 2021 embedded brains GmbH (http://www.embedded-brains.de) .. Copyright (C) 1988, 2008 On-Line Applications Research Corporation (OAR) +.. This file is part of the RTEMS quality process and was automatically +.. generated. If you find something that needs to be fixed or +.. worded better please post a report or patch to an RTEMS mailing list +.. or raise a bug report: +.. +.. https://www.rtems.org/bugs.html +.. +.. For information on updating and regenerating please refer to the How-To +.. section in the Software Requirements Engineering chapter of the +.. RTEMS Software Engineering manual. The manual is provided as a part of +.. a release. For development sources please refer to the online +.. documentation at: +.. +.. https://docs.rtems.org + +.. Generated from spec:/rtems/sem/if/group + +.. _SemaphoreManagerIntroduction: + Introduction ============ -The semaphore manager utilizes standard Dijkstra -counting semaphores to provide synchronization and mutual -exclusion capabilities. The directives provided by the -semaphore manager are: +.. The following list was generated from: +.. spec:/rtems/sem/if/create +.. spec:/rtems/sem/if/ident +.. spec:/rtems/sem/if/delete +.. spec:/rtems/sem/if/obtain +.. spec:/rtems/sem/if/release +.. spec:/rtems/sem/if/flush +.. spec:/rtems/sem/if/set-priority -- :ref:`rtems_semaphore_create` +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_ident` +* :ref:`InterfaceRtemsSemaphoreCreate` - Creates a semaphore. -- :ref:`rtems_semaphore_delete` +* :ref:`InterfaceRtemsSemaphoreIdent` - Identifies a semaphore by the object + name. -- :ref:`rtems_semaphore_obtain` +* :ref:`InterfaceRtemsSemaphoreDelete` - Deletes the semaphore. -- :ref:`rtems_semaphore_release` +* :ref:`InterfaceRtemsSemaphoreObtain` - Obtains the semaphore. -- :ref:`rtems_semaphore_flush` +* :ref:`InterfaceRtemsSemaphoreRelease` - Releases the semaphore. -- :ref:`rtems_semaphore_set_priority` +* :ref:`InterfaceRtemsSemaphoreFlush` - Flushes the semaphore. + +* :ref:`InterfaceRtemsSemaphoreSetPriority` - Sets the priority by scheduler + for the semaphore.