source: rtems-docs/c-user/semaphore_manager.rst @ 7c43a4b

5
Last change on this file since 7c43a4b was 7c43a4b, checked in by Sebastian Huber <sebastian.huber@…>, on 03/17/21 at 13:04:00

c-user: Update MrsP semaphore documentation

Update #4347.

  • Property mode set to 100644
File size: 34.9 KB
Line 
1.. SPDX-License-Identifier: CC-BY-SA-4.0
2
3.. Copyright (C) 1988, 2008 On-Line Applications Research Corporation (OAR)
4
5.. index:: semaphores
6.. index:: binary semaphores
7.. index:: counting semaphores
8.. index:: mutual exclusion
9
10Semaphore Manager
11*****************
12
13Introduction
14============
15
16The semaphore manager utilizes standard Dijkstra
17counting semaphores to provide synchronization and mutual
18exclusion capabilities.  The directives provided by the
19semaphore manager are:
20
21- rtems_semaphore_create_ - Create a semaphore
22
23- rtems_semaphore_ident_ - Get ID of a semaphore
24
25- rtems_semaphore_delete_ - Delete a semaphore
26
27- rtems_semaphore_obtain_ - Acquire a semaphore
28
29- rtems_semaphore_release_ - Release a semaphore
30
31- rtems_semaphore_flush_ - Unblock all tasks waiting on a semaphore
32
33- rtems_semaphore_set_priority_ - Set priority by scheduler for a semaphore
34
35Background
36==========
37
38A semaphore can be viewed as a protected variable whose value can be modified
39only with the ``rtems_semaphore_create``, ``rtems_semaphore_obtain``, and
40``rtems_semaphore_release`` directives.  RTEMS supports both binary and
41counting semaphores. A binary semaphore is restricted to values of zero or one,
42while a counting semaphore can assume any non-negative integer value.
43
44A binary semaphore (not a simple binary semaphore) can be used to control
45access to a single resource.  In particular, it can be used to enforce mutual
46exclusion for a critical section in user code (mutex).  In this instance, the
47semaphore would be created with an initial count of one to indicate that no
48task is executing the critical section of code.  Upon entry to the critical
49section, a task must issue the ``rtems_semaphore_obtain`` directive to prevent
50other tasks from entering the critical section.  Upon exit from the critical
51section, the task that obtained the binary semaphore must issue the
52``rtems_semaphore_release`` directive to allow another task to execute the
53critical section.  A binary semaphore must be released by the task that
54obtained it.
55
56A counting semaphore can be used to control access to a pool of two or more
57resources.  For example, access to three printers could be administered by a
58semaphore created with an initial count of three.  When a task requires access
59to one of the printers, it issues the ``rtems_semaphore_obtain`` directive to
60obtain access to a printer.  If a printer is not currently available, the task
61can wait for a printer to become available or return immediately.  When the
62task has completed printing, it should issue the ``rtems_semaphore_release``
63directive to allow other tasks access to the printer.
64
65Task synchronization may be achieved by creating a semaphore with an initial
66count of zero.  One task waits for the arrival of another task by issuing a
67``rtems_semaphore_obtain`` directive when it reaches a synchronization point.
68The other task performs a corresponding ``rtems_semaphore_release`` operation
69when it reaches its synchronization point, thus unblocking the pending task.
70
71.. _Nested Resource Access:
72
73Nested Resource Access
74----------------------
75
76Deadlock occurs when a task owning a binary semaphore attempts to acquire that
77same semaphore and blocks as result.  Since the semaphore is allocated to a
78task, it cannot be deleted.  Therefore, the task that currently holds the
79semaphore and is also blocked waiting for that semaphore will never execute
80again.
81
82RTEMS addresses this problem by allowing the task holding the binary semaphore
83to obtain the same binary semaphore multiple times in a nested manner.  Each
84``rtems_semaphore_obtain`` must be accompanied with a
85``rtems_semaphore_release``.  The semaphore will only be made available for
86acquisition by other tasks when the outermost ``rtems_semaphore_obtain`` is
87matched with a ``rtems_semaphore_release``.
88
89Simple binary semaphores do not allow nested access and so can be used for task
90synchronization.
91
92.. _Priority Inheritance:
93
94Priority Inheritance
95--------------------
96
97RTEMS supports :ref:`priority inheritance <PriorityInheritance>` for local,
98binary semaphores that use the priority task wait queue blocking discipline.
99In SMP configurations, the :ref:`OMIP` is used instead.
100
101.. _Priority Ceiling:
102
103Priority Ceiling
104----------------
105
106RTEMS supports :ref:`priority ceiling <PriorityCeiling>` for local, binary
107semaphores that use the priority task wait queue blocking discipline.
108
109.. _Multiprocessor Resource Sharing Protocol:
110
111Multiprocessor Resource Sharing Protocol
112----------------------------------------
113
114RTEMS supports the :ref:`MrsP` for local, binary semaphores that use the
115priority task wait queue blocking discipline.  In uniprocessor configurations,
116the :ref:`PriorityCeiling` is used instead.
117
118.. _Building a Semaphore Attribute Set:
119
120Building a Semaphore Attribute Set
121----------------------------------
122
123In general, an attribute set is built by a bitwise OR of the desired attribute
124components.  The following table lists the set of valid semaphore attributes:
125
126.. list-table::
127 :class: rtems-table
128
129 * - ``RTEMS_FIFO``
130   - tasks wait by FIFO (default)
131 * - ``RTEMS_PRIORITY``
132   - tasks wait by priority
133 * - ``RTEMS_BINARY_SEMAPHORE``
134   - restrict values to 0 and 1
135 * - ``RTEMS_COUNTING_SEMAPHORE``
136   - no restriction on values (default)
137 * - ``RTEMS_SIMPLE_BINARY_SEMAPHORE``
138   - restrict values to 0 and 1, do not allow nested access, allow deletion of
139     locked semaphore.
140 * - ``RTEMS_NO_INHERIT_PRIORITY``
141   - do not use priority inheritance (default)
142 * - ``RTEMS_INHERIT_PRIORITY``
143   - use priority inheritance
144 * - ``RTEMS_NO_PRIORITY_CEILING``
145   - do not use priority ceiling (default)
146 * - ``RTEMS_PRIORITY_CEILING``
147   - use priority ceiling
148 * - ``RTEMS_NO_MULTIPROCESSOR_RESOURCE_SHARING``
149   - do not use Multiprocessor Resource Sharing Protocol (default)
150 * - ``RTEMS_MULTIPROCESSOR_RESOURCE_SHARING``
151   - use Multiprocessor Resource Sharing Protocol
152 * - ``RTEMS_LOCAL``
153   - local semaphore (default)
154 * - ``RTEMS_GLOBAL``
155   - global semaphore
156
157Attribute values are specifically designed to be mutually exclusive, therefore
158bitwise OR and addition operations are equivalent as long as each attribute
159appears exactly once in the component list.  An attribute listed as a default
160is not required to appear in the attribute list, although it is a good
161programming practice to specify default attributes.  If all defaults are
162desired, the attribute ``RTEMS_DEFAULT_ATTRIBUTES`` should be specified on this
163call.
164
165This example demonstrates the attribute_set parameter needed to create a local
166semaphore with the task priority waiting queue discipline.  The attribute_set
167parameter passed to the ``rtems_semaphore_create`` directive could be either
168``RTEMS_PRIORITY`` or ``RTEMS_LOCAL | RTEMS_PRIORITY``.  The attribute_set
169parameter can be set to ``RTEMS_PRIORITY`` because ``RTEMS_LOCAL`` is the
170default for all created tasks.  If a similar semaphore were to be known
171globally, then the attribute_set parameter would be ``RTEMS_GLOBAL |
172RTEMS_PRIORITY``.
173
174Some combinatinos of these attributes are invalid.  For example, priority
175ordered blocking discipline must be applied to a binary semaphore in order to
176use either the priority inheritance or priority ceiling functionality.  The
177following tree figure illustrates the valid combinations.
178
179.. figure:: ../images/c_user/semaphore_attributes.png
180         :width: 90%
181         :align: center
182         :alt: Semaphore Attributes
183
184.. _Building a SEMAPHORE_OBTAIN Option Set:
185
186Building a SEMAPHORE_OBTAIN Option Set
187--------------------------------------
188
189In general, an option is built by a bitwise OR of the desired option
190components.  The set of valid options for the ``rtems_semaphore_obtain``
191directive are listed in the following table:
192
193.. list-table::
194 :class: rtems-table
195
196 * - ``RTEMS_WAIT``
197   - task will wait for semaphore (default)
198 * - ``RTEMS_NO_WAIT``
199   - task should not wait
200
201Option values are specifically designed to be mutually exclusive, therefore
202bitwise OR and addition operations are equivalent as long as each attribute
203appears exactly once in the component list.  An option listed as a default is
204not required to appear in the list, although it is a good programming practice
205to specify default options.  If all defaults are desired, the option
206``RTEMS_DEFAULT_OPTIONS`` should be specified on this call.
207
208This example demonstrates the option parameter needed to poll for a semaphore.
209The option parameter passed to the ``rtems_semaphore_obtain`` directive should
210be ``RTEMS_NO_WAIT``.
211
212Operations
213==========
214
215.. _Creating a Semaphore:
216
217Creating a Semaphore
218--------------------
219
220The ``rtems_semaphore_create`` directive creates a binary or counting semaphore
221with a user-specified name as well as an initial count.  If a binary semaphore
222is created with a count of zero (0) to indicate that it has been allocated,
223then the task creating the semaphore is considered the current holder of the
224semaphore.  At create time the method for ordering waiting tasks in the
225semaphore's task wait queue (by FIFO or task priority) is specified.
226Additionally, the priority inheritance or priority ceiling algorithm may be
227selected for local, binary semaphores that use the priority task wait queue
228blocking discipline.  If the priority ceiling algorithm is selected, then the
229highest priority of any task which will attempt to obtain this semaphore must
230be specified.  RTEMS allocates a Semaphore Control Block (SMCB) from the SMCB
231free list.  This data structure is used by RTEMS to manage the newly created
232semaphore.  Also, a unique semaphore ID is generated and returned to the
233calling task.
234
235.. _Obtaining Semaphore IDs:
236
237Obtaining Semaphore IDs
238-----------------------
239
240When a semaphore is created, RTEMS generates a unique semaphore ID and assigns
241it to the created semaphore until it is deleted.  The semaphore ID may be
242obtained by either of two methods.  First, as the result of an invocation of
243the ``rtems_semaphore_create`` directive, the semaphore ID is stored in a user
244provided location.  Second, the semaphore ID may be obtained later using the
245``rtems_semaphore_ident`` directive.  The semaphore ID is used by other
246semaphore manager directives to access this semaphore.
247
248.. _Acquiring a Semaphore:
249
250Acquiring a Semaphore
251---------------------
252
253The ``rtems_semaphore_obtain`` directive is used to acquire the
254specified semaphore.  A simplified version of the ``rtems_semaphore_obtain``
255directive can be described as follows:
256
257    If the semaphore's count is greater than zero then decrement the
258    semaphore's count else wait for release of semaphore then return
259    SUCCESSFUL.
260
261When the semaphore cannot be immediately acquired, one of the following
262situations applies:
263
264- By default, the calling task will wait forever to acquire the semaphore.
265
266- Specifying ``RTEMS_NO_WAIT`` forces an immediate return with an error status
267  code.
268
269- Specifying a timeout limits the interval the task will wait before returning
270  with an error status code.
271
272If the task waits to acquire the semaphore, then it is placed in the
273semaphore's task wait queue in either FIFO or task priority order.  If the task
274blocked waiting for a binary semaphore using priority inheritance and the
275task's priority is greater than that of the task currently holding the
276semaphore, then the holding task will inherit the priority of the blocking
277task.  All tasks waiting on a semaphore are returned an error code when the
278semaphore is deleted.
279
280When a task successfully obtains a semaphore using priority ceiling and the
281priority ceiling for this semaphore is greater than that of the holder, then
282the holder's priority will be elevated.
283
284.. _Releasing a Semaphore:
285
286Releasing a Semaphore
287---------------------
288
289The ``rtems_semaphore_release`` directive is used to release the specified
290semaphore.  A simplified version of the ``rtems_semaphore_release`` directive
291can be described as follows:
292
293    If there are no tasks are waiting on this semaphore then increment the
294    semaphore's count else assign semaphore to a waiting task and return
295    SUCCESSFUL.
296
297If this is the outermost release of a binary semaphore that uses priority
298inheritance or priority ceiling and the task does not currently hold any other
299binary semaphores, then the task performing the ``rtems_semaphore_release``
300will have its priority restored to its normal value.
301
302.. _Deleting a Semaphore:
303
304Deleting a Semaphore
305--------------------
306
307The ``rtems_semaphore_delete`` directive removes a semaphore from the system
308and frees its control block.  A semaphore can be deleted by any local task that
309knows the semaphore's ID.  As a result of this directive, all tasks blocked
310waiting to acquire the semaphore will be readied and returned a status code
311which indicates that the semaphore was deleted.  Any subsequent references to
312the semaphore's name and ID are invalid.
313
314Directives
315==========
316
317This section details the semaphore manager's directives.  A subsection is
318dedicated to each of this manager's directives and describes the calling
319sequence, related constants, usage, and status codes.
320
321.. raw:: latex
322
323   \clearpage
324
325.. index:: create a semaphore
326.. index:: rtems_semaphore_create
327
328.. _rtems_semaphore_create:
329
330SEMAPHORE_CREATE - Create a semaphore
331-------------------------------------
332
333
334CALLING SEQUENCE:
335    .. code-block:: c
336
337        rtems_status_code rtems_semaphore_create(
338            rtems_name           name,
339            uint32_t             count,
340            rtems_attribute      attribute_set,
341            rtems_task_priority  priority_ceiling,
342            rtems_id            *id
343        );
344
345DIRECTIVE STATUS CODES:
346    .. list-table::
347     :class: rtems-table
348
349     * - ``RTEMS_SUCCESSFUL``
350       - semaphore created successfully
351     * - ``RTEMS_INVALID_NAME``
352       - invalid semaphore name
353     * - ``RTEMS_INVALID_ADDRESS``
354       - ``id`` is NULL
355     * - ``RTEMS_TOO_MANY``
356       - too many semaphores created
357     * - ``RTEMS_NOT_DEFINED``
358       - invalid attribute set
359     * - ``RTEMS_INVALID_NUMBER``
360       - invalid starting count for binary semaphore
361     * - ``RTEMS_TOO_MANY``
362       - too many global objects
363
364DESCRIPTION:
365    This directive creates a semaphore which resides on the local node. The
366    created semaphore has the user-defined name specified in name and the
367    initial count specified in count.  For control and maintenance of the
368    semaphore, RTEMS allocates and initializes a SMCB.  The RTEMS-assigned
369    semaphore id is returned in id.  This semaphore id is used with other
370    semaphore related directives to access the semaphore.
371
372    Specifying PRIORITY in attribute_set causes tasks waiting for a semaphore
373    to be serviced according to task priority.  When FIFO is selected, tasks
374    are serviced in First In-First Out order.
375
376NOTES:
377    This directive may cause the calling task to be preempted due to an
378    obtain and release of the object allocator mutex.
379
380    The priority inheritance, priority ceiling, and MrsP algorithms are only
381    supported for local, binary semaphores that use the priority task wait
382    queue blocking discipline.
383
384    The following semaphore attribute constants are defined by RTEMS:
385
386    .. list-table::
387     :class: rtems-table
388
389     * - ``RTEMS_FIFO``
390       - tasks wait by FIFO (default)
391     * - ``RTEMS_PRIORITY``
392       - tasks wait by priority
393     * - ``RTEMS_BINARY_SEMAPHORE``
394       - restrict values to 0 and 1
395     * - ``RTEMS_COUNTING_SEMAPHORE``
396       - no restriction on values (default)
397     * - ``RTEMS_SIMPLE_BINARY_SEMAPHORE``
398       - restrict values to 0 and 1, block on nested access, allow deletion of locked semaphore.
399     * - ``RTEMS_NO_INHERIT_PRIORITY``
400       - do not use priority inheritance (default)
401     * - ``RTEMS_INHERIT_PRIORITY``
402       - use priority inheritance
403     * - ``RTEMS_NO_PRIORITY_CEILING``
404       - do not use priority ceiling (default)
405     * - ``RTEMS_PRIORITY_CEILING``
406       - use priority ceiling
407     * - ``RTEMS_NO_MULTIPROCESSOR_RESOURCE_SHARING``
408       - do not use Multiprocessor Resource Sharing Protocol (default)
409     * - ``RTEMS_MULTIPROCESSOR_RESOURCE_SHARING``
410       - use Multiprocessor Resource Sharing Protocol
411     * - ``RTEMS_LOCAL``
412       - local semaphore (default)
413     * - ``RTEMS_GLOBAL``
414       - global semaphore
415
416    Semaphores should not be made global unless remote tasks must interact with
417    the created semaphore.  This is to avoid the system overhead incurred by
418    the creation of a global semaphore.  When a global semaphore is created,
419    the semaphore's name and id must be transmitted to every node in the system
420    for insertion in the local copy of the global object table.
421
422    *Note*, some combinations of attributes are not valid.  See the earlier
423    discussion on this.
424
425    The total number of global objects, including semaphores, is limited by the
426    maximum_global_objects field in the Configuration Table.
427
428    It is not allowed to create an initially locked MrsP semaphore and the
429    ``RTEMS_INVALID_NUMBER`` status code will be returned in SMP configurations
430    in this case.  This prevents lock order reversal problems with the
431    allocator mutex.
432
433.. raw:: latex
434
435   \clearpage
436
437.. index:: get ID of a semaphore
438.. index:: obtain ID of a semaphore
439.. index:: rtems_semaphore_ident
440
441.. _rtems_semaphore_ident:
442
443SEMAPHORE_IDENT - Get ID of a semaphore
444---------------------------------------
445
446CALLING SEQUENCE:
447    .. code-block:: c
448
449        rtems_status_code rtems_semaphore_ident(
450            rtems_name  name,
451            uint32_t    node,
452            rtems_id   *id
453        );
454
455DIRECTIVE STATUS CODES:
456    .. list-table::
457     :class: rtems-table
458
459     * - ``RTEMS_SUCCESSFUL``
460       - semaphore identified successfully
461     * - ``RTEMS_INVALID_NAME``
462       - semaphore name not found
463     * - ``RTEMS_INVALID_NODE``
464       - invalid node id
465
466DESCRIPTION:
467    This directive obtains the semaphore id associated with the semaphore name.
468    If the semaphore name is not unique, then the semaphore id will match one
469    of the semaphores with that name.  However, this semaphore id is not
470    guaranteed to correspond to the desired semaphore.  The semaphore id is
471    used by other semaphore related directives to access the semaphore.
472
473NOTES:
474    This directive will not cause the running task to be preempted.
475
476    If node is ``RTEMS_SEARCH_ALL_NODES``, all nodes are searched with the
477    local node being searched first.  All other nodes are searched with the
478    lowest numbered node searched first.
479
480    If node is a valid node number which does not represent the local node,
481    then only the semaphores exported by the designated node are searched.
482
483    This directive does not generate activity on remote nodes.  It accesses
484    only the local copy of the global object table.
485
486.. raw:: latex
487
488   \clearpage
489
490.. index:: delete a semaphore
491.. index:: rtems_semaphore_delete
492
493.. _rtems_semaphore_delete:
494
495SEMAPHORE_DELETE - Delete a semaphore
496-------------------------------------
497
498CALLING SEQUENCE:
499    .. code-block:: c
500
501        rtems_status_code rtems_semaphore_delete(
502            rtems_id id
503        );
504
505DIRECTIVE STATUS CODES:
506    .. list-table::
507     :class: rtems-table
508
509     * - ``RTEMS_SUCCESSFUL``
510       - semaphore deleted successfully
511     * - ``RTEMS_INVALID_ID``
512       - invalid semaphore id
513     * - ``RTEMS_RESOURCE_IN_USE``
514       - binary semaphore is in use
515     * - ``RTEMS_ILLEGAL_ON_REMOTE_OBJECT``
516       - cannot delete remote semaphore
517
518DESCRIPTION:
519    This directive deletes the semaphore specified by ``id``.  All tasks
520    blocked waiting to acquire the semaphore will be readied and returned a
521    status code which indicates that the semaphore was deleted.  The SMCB for
522    this semaphore is reclaimed by RTEMS.
523
524NOTES:
525    This directive may cause the calling task to be preempted due to an
526    obtain and release of the object allocator mutex.
527
528    The calling task will be preempted if it is enabled by the task's execution
529    mode and a higher priority local task is waiting on the deleted semaphore.
530    The calling task will NOT be preempted if all of the tasks that are waiting
531    on the semaphore are remote tasks.
532
533    The calling task does not have to be the task that created the semaphore.  Any
534    local task that knows the semaphore id can delete the semaphore.
535
536    When a global semaphore is deleted, the semaphore id must be transmitted to
537    every node in the system for deletion from the local copy of the global
538    object table.
539
540    The semaphore must reside on the local node, even if the semaphore was
541    created with the ``RTEMS_GLOBAL`` option.
542
543    Proxies, used to represent remote tasks, are reclaimed when the semaphore
544    is deleted.
545
546.. raw:: latex
547
548   \clearpage
549
550.. index:: obtain a semaphore
551.. index:: lock a semaphore
552.. index:: rtems_semaphore_obtain
553
554.. _rtems_semaphore_obtain:
555
556SEMAPHORE_OBTAIN - Acquire a semaphore
557--------------------------------------
558
559CALLING SEQUENCE:
560    .. code-block:: c
561
562        rtems_status_code rtems_semaphore_obtain(
563            rtems_id        id,
564            rtems_option    option_set,
565            rtems_interval  timeout
566        );
567
568DIRECTIVE STATUS CODES:
569    .. list-table::
570     :class: rtems-table
571
572     * - ``RTEMS_SUCCESSFUL``
573       - semaphore obtained successfully
574     * - ``RTEMS_UNSATISFIED``
575       - semaphore not available
576     * - ``RTEMS_TIMEOUT``
577       - timed out waiting for semaphore
578     * - ``RTEMS_OBJECT_WAS_DELETED``
579       - semaphore deleted while waiting
580     * - ``RTEMS_INVALID_ID``
581       - invalid semaphore id
582
583DESCRIPTION:
584    This directive acquires the semaphore specified by id.  The ``RTEMS_WAIT``
585    and ``RTEMS_NO_WAIT`` components of the options parameter indicate whether
586    the calling task wants to wait for the semaphore to become available or
587    return immediately if the semaphore is not currently available.  With
588    either ``RTEMS_WAIT`` or ``RTEMS_NO_WAIT``, if the current semaphore count
589    is positive, then it is decremented by one and the semaphore is
590    successfully acquired by returning immediately with a successful return
591    code.
592
593    If the calling task chooses to return immediately and the current semaphore
594    count is zero or negative, then a status code is returned indicating that
595    the semaphore is not available. If the calling task chooses to wait for a
596    semaphore and the current semaphore count is zero or negative, then it is
597    decremented by one and the calling task is placed on the semaphore's wait
598    queue and blocked.  If the semaphore was created with the
599    ``RTEMS_PRIORITY`` attribute, then the calling task is inserted into the
600    queue according to its priority.  However, if the semaphore was created
601    with the ``RTEMS_FIFO`` attribute, then the calling task is placed at the
602    rear of the wait queue.  If the binary semaphore was created with the
603    ``RTEMS_INHERIT_PRIORITY`` attribute, then the priority of the task
604    currently holding the binary semaphore is guaranteed to be greater than or
605    equal to that of the blocking task.  If the binary semaphore was created
606    with the ``RTEMS_PRIORITY_CEILING`` attribute, a task successfully obtains
607    the semaphore, and the priority of that task is greater than the ceiling
608    priority for this semaphore, then the priority of the task obtaining the
609    semaphore is elevated to that of the ceiling.
610
611    The timeout parameter specifies the maximum interval the calling task is
612    willing to be blocked waiting for the semaphore.  If it is set to
613    ``RTEMS_NO_TIMEOUT``, then the calling task will wait forever.  If the
614    semaphore is available or the ``RTEMS_NO_WAIT`` option component is set,
615    then timeout is ignored.
616
617    In case a semaphore is not available, then ``RTEMS_UNSATISFIED`` will be
618    returned.  This happens immediately in case ``RTEMS_NO_WAIT`` is specified,
619    or as a result of another task invoking the ``rtems_semaphore_flush``
620    directive in case ``RTEMS_WAIT`` is specified.
621
622    Deadlock situations are detected for MrsP semaphores and the
623    ``RTEMS_UNSATISFIED`` status code will be returned in SMP configurations in
624    this case.
625
626NOTES:
627    The following semaphore acquisition option constants are defined by RTEMS:
628
629    .. list-table::
630     :class: rtems-table
631
632     * - ``RTEMS_WAIT``
633       - task will wait for semaphore (default)
634     * - ``RTEMS_NO_WAIT``
635       - task should not wait
636
637    Attempting to obtain a global semaphore which does not reside on the local
638    node will generate a request to the remote node to access the semaphore.
639    If the semaphore is not available and ``RTEMS_NO_WAIT`` was not specified,
640    then the task must be blocked until the semaphore is released.  A proxy is
641    allocated on the remote node to represent the task until the semaphore is
642    released.
643
644    A clock tick is required to support the timeout functionality of this
645    directive.
646
647    It is not allowed to obtain a MrsP semaphore more than once by one task at
648    a time (nested access) and the ``RTEMS_UNSATISFIED`` status code will be
649    returned in SMP configurations in this case.
650
651.. raw:: latex
652
653   \clearpage
654
655.. index:: release a semaphore
656.. index:: unlock a semaphore
657.. index:: rtems_semaphore_release
658
659.. _rtems_semaphore_release:
660
661SEMAPHORE_RELEASE - Release a semaphore
662---------------------------------------
663
664CALLING SEQUENCE:
665    .. code-block:: c
666
667        rtems_status_code rtems_semaphore_release(
668            rtems_id id
669        );
670
671DIRECTIVE STATUS CODES:
672    .. list-table::
673     :class: rtems-table
674
675     * - ``RTEMS_SUCCESSFUL``
676       - semaphore released successfully
677     * - ``RTEMS_INVALID_ID``
678       - invalid semaphore id
679     * - ``RTEMS_NOT_OWNER_OF_RESOURCE``
680       - calling task does not own semaphore
681     * - ``RTEMS_INCORRECT_STATE``
682       - invalid unlock order
683
684DESCRIPTION:
685    This directive releases the semaphore specified by id.  The semaphore count
686    is incremented by one.  If the count is zero or negative, then the first
687    task on this semaphore's wait queue is removed and unblocked.  The
688    unblocked task may preempt the running task if the running task's
689    preemption mode is enabled and the unblocked task has a higher priority
690    than the running task.
691
692NOTES:
693    The calling task may be preempted if it causes a higher priority task to be
694    made ready for execution.
695
696    Releasing a global semaphore which does not reside on the local node will
697    generate a request telling the remote node to release the semaphore.
698
699    If the task to be unblocked resides on a different node from the semaphore,
700    then the semaphore allocation is forwarded to the appropriate node, the
701    waiting task is unblocked, and the proxy used to represent the task is
702    reclaimed.
703
704    The outermost release of a local, binary, priority inheritance or priority
705    ceiling semaphore may result in the calling task having its priority
706    lowered.  This will occur if the calling task holds no other binary
707    semaphores and it has inherited a higher priority.
708
709    The MrsP semaphores must be released in the reversed obtain order,
710    otherwise the ``RTEMS_INCORRECT_STATE`` status code will be returned in SMP
711    configurations in this case.
712
713.. raw:: latex
714
715   \clearpage
716
717.. index:: flush a semaphore
718.. index:: unblock all tasks waiting on a semaphore
719.. index:: rtems_semaphore_flush
720
721.. _rtems_semaphore_flush:
722
723SEMAPHORE_FLUSH - Unblock all tasks waiting on a semaphore
724----------------------------------------------------------
725
726CALLING SEQUENCE:
727    .. code-block:: c
728
729        rtems_status_code rtems_semaphore_flush(
730            rtems_id id
731        );
732
733DIRECTIVE STATUS CODES:
734    .. list-table::
735     :class: rtems-table
736
737     * - ``RTEMS_SUCCESSFUL``
738       - semaphore released successfully
739     * - ``RTEMS_INVALID_ID``
740       - invalid semaphore id
741     * - ``RTEMS_NOT_DEFINED``
742       - operation not defined for the protocol of the semaphore
743     * - ``RTEMS_ILLEGAL_ON_REMOTE_OBJECT``
744       - not supported for remote semaphores
745
746DESCRIPTION:
747    This directive unblocks all tasks waiting on the semaphore specified by id.
748    Since there are tasks blocked on the semaphore, the semaphore's count is
749    not changed by this directive and thus is zero before and after this
750    directive is executed.  Tasks which are unblocked as the result of this
751    directive will return from the ``rtems_semaphore_obtain`` directive with a
752    status code of ``RTEMS_UNSATISFIED`` to indicate that the semaphore was not
753    obtained.
754
755    This directive may unblock any number of tasks.  Any of the unblocked tasks
756    may preempt the running task if the running task's preemption mode is
757    enabled and an unblocked task has a higher priority than the running task.
758
759NOTES:
760    The calling task may be preempted if it causes a higher priority task to be
761    made ready for execution.
762
763    If the task to be unblocked resides on a different node from the semaphore,
764    then the waiting task is unblocked, and the proxy used to represent the
765    task is reclaimed.
766
767    It is not allowed to flush a MrsP semaphore and the ``RTEMS_NOT_DEFINED``
768    status code will be returned in SMP configurations in this case.
769
770    Using the ``rtems_semaphore_flush`` directive for condition synchronization
771    in concert with another semaphore may be subject to the lost wake-up
772    problem.  The following attempt to implement a condition variable is
773    broken.
774
775    .. code-block:: c
776
777        #include <rtems.h>
778        #include <assert.h>
779
780        void cnd_wait( rtems_id cnd, rtems_id mtx )
781        {
782          rtems_status_code sc;
783
784          sc = rtems_semaphore_release( mtx );
785          assert( sc == RTEMS_SUCCESSFUL );
786
787          /*
788           * Here, a higher priority task may run and satisfy the condition. We
789           * may never wake up from the next semaphore obtain.
790           */
791
792          sc = rtems_semaphore_obtain( cnd, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
793          assert( sc == RTEMS_UNSATISFIED );
794
795          sc = rtems_semaphore_obtain( mtx, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
796          assert( sc == RTEMS_SUCCESSFUL );
797        }
798
799        void cnd_broadcast( rtems_id cnd )
800        {
801          rtems_status_code sc;
802
803          sc = rtems_semaphore_flush( cnd );
804          assert( sc == RTEMS_SUCCESSFUL );
805        }
806
807    For barrier synchronization, the :ref:`barrier_manager` offers a cleaner
808    alternative to using the `rtems_semaphore_flush` directive.  Unlike POSIX
809    barriers, they have a manual release option.
810
811.. raw:: latex
812
813   \clearpage
814
815.. index:: set priority by scheduler for a semaphore
816.. index:: rtems_semaphore_set_priority
817
818.. _rtems_semaphore_set_priority:
819
820SEMAPHORE_SET_PRIORITY - Set priority by scheduler for a semaphore
821------------------------------------------------------------------
822
823CALLING SEQUENCE:
824    .. code-block:: c
825
826        rtems_status_code rtems_semaphore_set_priority(
827            rtems_id             semaphore_id,
828            rtems_id             scheduler_id,
829            rtems_task_priority  new_priority,
830            rtems_task_priority *old_priority
831        );
832
833DIRECTIVE STATUS CODES:
834    .. list-table::
835     :class: rtems-table
836
837     * - ``RTEMS_SUCCESSFUL``
838       - successful operation
839     * - ``RTEMS_INVALID_ID``
840       - invalid semaphore or scheduler id
841     * - ``RTEMS_INVALID_ADDRESS``
842       - ``old_priority`` is NULL
843     * - ``RTEMS_INVALID_PRIORITY``
844       - invalid new priority value
845     * - ``RTEMS_NOT_DEFINED``
846       - operation not defined for the protocol ofthe semaphore
847     * - ``RTEMS_ILLEGAL_ON_REMOTE_OBJECT``
848       - not supported for remote semaphores
849
850DESCRIPTION:
851    This directive sets the priority value with respect to the specified
852    scheduler of a semaphore.
853
854    The special priority value ``RTEMS_CURRENT_PRIORITY`` can be used to get
855    the current priority value without changing it.
856
857    The interpretation of the priority value depends on the protocol of the
858    semaphore object.
859
860    - The Multiprocessor Resource Sharing Protocol needs a ceiling priority per
861      scheduler instance.  This operation can be used to specify these priority
862      values.
863
864    - For the Priority Ceiling Protocol the ceiling priority is used with this
865      operation.
866
867    - For other protocols this operation is not defined.
868
869EXAMPLE:
870    .. code-block:: c
871        :linenos:
872
873        #include <assert.h>
874        #include <stdlib.h>
875        #include <rtems.h>
876
877        #define SCHED_A rtems_build_name(' ', ' ', ' ', 'A')
878        #define SCHED_B rtems_build_name(' ', ' ', ' ', 'B')
879
880        static void Init(rtems_task_argument arg)
881        {
882            rtems_status_code   sc;
883            rtems_id            semaphore_id;
884            rtems_id            scheduler_a_id;
885            rtems_id            scheduler_b_id;
886            rtems_task_priority prio;
887
888            /* Get the scheduler identifiers */
889            sc = rtems_scheduler_ident(SCHED_A, &scheduler_a_id);
890            assert(sc == RTEMS_SUCCESSFUL);
891            sc = rtems_scheduler_ident(SCHED_B, &scheduler_b_id);
892            assert(sc == RTEMS_SUCCESSFUL);
893
894            /* Create a MrsP semaphore object */
895            sc = rtems_semaphore_create(
896                rtems_build_name('M', 'R', 'S', 'P'),
897                1,
898                RTEMS_MULTIPROCESSOR_RESOURCE_SHARING | RTEMS_BINARY_SEMAPHORE,
899                1,
900                &semaphore_id
901            );
902            assert(sc == RTEMS_SUCCESSFUL);
903
904            /*
905             * The ceiling priority values per scheduler are equal to the value specified
906             * for object creation.
907             */
908            prio = RTEMS_CURRENT_PRIORITY;
909            sc = rtems_semaphore_set_priority(semaphore_id, scheduler_a_id, prio, &prio);
910            assert(sc == RTEMS_SUCCESSFUL);
911            assert(prio == 1);
912
913            /* Check the old value and set a new ceiling priority for scheduler B */
914            prio = 2;
915            sc = rtems_semaphore_set_priority(semaphore_id, scheduler_b_id, prio, &prio);
916            assert(sc == RTEMS_SUCCESSFUL);
917            assert(prio == 1);
918
919            /* Check the ceiling priority values */
920            prio = RTEMS_CURRENT_PRIORITY;
921            sc = rtems_semaphore_set_priority(semaphore_id, scheduler_a_id, prio, &prio);
922            assert(sc == RTEMS_SUCCESSFUL);
923            assert(prio == 1);
924            prio = RTEMS_CURRENT_PRIORITY;
925            sc = rtems_semaphore_set_priority(semaphore_id, scheduler_b_id, prio, &prio);
926            assert(sc == RTEMS_SUCCESSFUL);
927            assert(prio == 2);
928
929            sc = rtems_semaphore_delete(semaphore_id);
930            assert(sc == RTEMS_SUCCESSFUL);
931
932            exit(0);
933        }
934
935        #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
936        #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
937        #define CONFIGURE_MAXIMUM_TASKS 1
938        #define CONFIGURE_MAXIMUM_SEMAPHORES 1
939        #define CONFIGURE_MAXIMUM_PROCESSORS 2
940
941        #define CONFIGURE_SCHEDULER_SIMPLE_SMP
942
943        #include <rtems/scheduler.h>
944
945        RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(a);
946        RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(b);
947
948        #define CONFIGURE_SCHEDULER_TABLE_ENTRIES \
949            RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(a, SCHED_A), \
950            RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(b, SCHED_B)
951
952        #define CONFIGURE_SCHEDULER_ASSIGNMENTS \
953            RTEMS_SCHEDULER_ASSIGN(0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY), \
954            RTEMS_SCHEDULER_ASSIGN(1, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY)
955
956        #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
957        #define CONFIGURE_INIT
958
959        #include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.