source: rtems-docs/c-user/semaphore_manager.rst @ 0acf49e

5
Last change on this file since 0acf49e was 0acf49e, checked in by Sebastian Huber <sebastian.huber@…>, on 11/20/17 at 07:25:26

Mention barrier manager in rtems_semaphore_flush()

  • Property mode set to 100644
File size: 34.9 KB
Line 
1.. comment SPDX-License-Identifier: CC-BY-SA-4.0
2
3.. COMMENT: COPYRIGHT (c) 1988-2008.
4.. COMMENT: On-Line Applications Research Corporation (OAR).
5.. COMMENT: All rights reserved.
6
7.. index:: semaphores
8.. index:: binary semaphores
9.. index:: counting semaphores
10.. index:: mutual exclusion
11
12Semaphore Manager
13*****************
14
15Introduction
16============
17
18The semaphore manager utilizes standard Dijkstra
19counting semaphores to provide synchronization and mutual
20exclusion capabilities.  The directives provided by the
21semaphore manager are:
22
23- rtems_semaphore_create_ - Create a semaphore
24
25- rtems_semaphore_ident_ - Get ID of a semaphore
26
27- rtems_semaphore_delete_ - Delete a semaphore
28
29- rtems_semaphore_obtain_ - Acquire a semaphore
30
31- rtems_semaphore_release_ - Release a semaphore
32
33- rtems_semaphore_flush_ - Unblock all tasks waiting on a semaphore
34
35- rtems_semaphore_set_priority_ - Set priority by scheduler for a semaphore
36
37Background
38==========
39
40A semaphore can be viewed as a protected variable whose value can be modified
41only with the ``rtems_semaphore_create``, ``rtems_semaphore_obtain``, and
42``rtems_semaphore_release`` directives.  RTEMS supports both binary and
43counting semaphores. A binary semaphore is restricted to values of zero or one,
44while a counting semaphore can assume any non-negative integer value.
45
46A binary semaphore (not a simple binary semaphore) can be used to control
47access to a single resource.  In particular, it can be used to enforce mutual
48exclusion for a critical section in user code (mutex).  In this instance, the
49semaphore would be created with an initial count of one to indicate that no
50task is executing the critical section of code.  Upon entry to the critical
51section, a task must issue the ``rtems_semaphore_obtain`` directive to prevent
52other tasks from entering the critical section.  Upon exit from the critical
53section, the task that obtained the binary semaphore must issue the
54``rtems_semaphore_release`` directive to allow another task to execute the
55critical section.  A binary semaphore must be released by the task that
56obtained it.
57
58A counting semaphore can be used to control access to a pool of two or more
59resources.  For example, access to three printers could be administered by a
60semaphore created with an initial count of three.  When a task requires access
61to one of the printers, it issues the ``rtems_semaphore_obtain`` directive to
62obtain access to a printer.  If a printer is not currently available, the task
63can wait for a printer to become available or return immediately.  When the
64task has completed printing, it should issue the ``rtems_semaphore_release``
65directive to allow other tasks access to the printer.
66
67Task synchronization may be achieved by creating a semaphore with an initial
68count of zero.  One task waits for the arrival of another task by issuing a
69``rtems_semaphore_obtain`` directive when it reaches a synchronization point.
70The other task performs a corresponding ``rtems_semaphore_release`` operation
71when it reaches its synchronization point, thus unblocking the pending task.
72
73.. _Nested Resource Access:
74
75Nested Resource Access
76----------------------
77
78Deadlock occurs when a task owning a binary semaphore attempts to acquire that
79same semaphore and blocks as result.  Since the semaphore is allocated to a
80task, it cannot be deleted.  Therefore, the task that currently holds the
81semaphore and is also blocked waiting for that semaphore will never execute
82again.
83
84RTEMS addresses this problem by allowing the task holding the binary semaphore
85to obtain the same binary semaphore multiple times in a nested manner.  Each
86``rtems_semaphore_obtain`` must be accompanied with a
87``rtems_semaphore_release``.  The semaphore will only be made available for
88acquisition by other tasks when the outermost ``rtems_semaphore_obtain`` is
89matched with a ``rtems_semaphore_release``.
90
91Simple binary semaphores do not allow nested access and so can be used for task
92synchronization.
93
94.. _Priority Inheritance:
95
96Priority Inheritance
97--------------------
98
99RTEMS supports :ref:`priority inheritance <PriorityInheritance>` for local,
100binary semaphores that use the priority task wait queue blocking discipline.
101In SMP configurations, the :ref:`OMIP` is used instead.
102
103.. _Priority Ceiling:
104
105Priority Ceiling
106----------------
107
108RTEMS supports :ref:`priority ceiling <PriorityCeiling>` for local, binary
109semaphores that use the priority task wait queue blocking discipline.
110
111.. _Multiprocessor Resource Sharing Protocol:
112
113Multiprocessor Resource Sharing Protocol
114----------------------------------------
115
116RTEMS supports the :ref:`MrsP` for local, binary semaphores that use the
117priority task wait queue blocking discipline.  In uni-processor configurations,
118the :ref:`PriorityCeiling` is used instead.
119
120.. _Building a Semaphore Attribute Set:
121
122Building a Semaphore Attribute Set
123----------------------------------
124
125In general, an attribute set is built by a bitwise OR of the desired attribute
126components.  The following table lists the set of valid semaphore attributes:
127
128.. list-table::
129 :class: rtems-table
130
131 * - ``RTEMS_FIFO``
132   - tasks wait by FIFO (default)
133 * - ``RTEMS_PRIORITY``
134   - tasks wait by priority
135 * - ``RTEMS_BINARY_SEMAPHORE``
136   - restrict values to 0 and 1
137 * - ``RTEMS_COUNTING_SEMAPHORE``
138   - no restriction on values (default)
139 * - ``RTEMS_SIMPLE_BINARY_SEMAPHORE``
140   - restrict values to 0 and 1, do not allow nested access, allow deletion of
141     locked semaphore.
142 * - ``RTEMS_NO_INHERIT_PRIORITY``
143   - do not use priority inheritance (default)
144 * - ``RTEMS_INHERIT_PRIORITY``
145   - use priority inheritance
146 * - ``RTEMS_NO_PRIORITY_CEILING``
147   - do not use priority ceiling (default)
148 * - ``RTEMS_PRIORITY_CEILING``
149   - use priority ceiling
150 * - ``RTEMS_NO_MULTIPROCESSOR_RESOURCE_SHARING``
151   - do not use Multiprocessor Resource Sharing Protocol (default)
152 * - ``RTEMS_MULTIPROCESSOR_RESOURCE_SHARING``
153   - use Multiprocessor Resource Sharing Protocol
154 * - ``RTEMS_LOCAL``
155   - local semaphore (default)
156 * - ``RTEMS_GLOBAL``
157   - global semaphore
158
159Attribute values are specifically designed to be mutually exclusive, therefore
160bitwise OR and addition operations are equivalent as long as each attribute
161appears exactly once in the component list.  An attribute listed as a default
162is not required to appear in the attribute list, although it is a good
163programming practice to specify default attributes.  If all defaults are
164desired, the attribute ``RTEMS_DEFAULT_ATTRIBUTES`` should be specified on this
165call.
166
167This example demonstrates the attribute_set parameter needed to create a local
168semaphore with the task priority waiting queue discipline.  The attribute_set
169parameter passed to the ``rtems_semaphore_create`` directive could be either
170``RTEMS_PRIORITY`` or ``RTEMS_LOCAL | RTEMS_PRIORITY``.  The attribute_set
171parameter can be set to ``RTEMS_PRIORITY`` because ``RTEMS_LOCAL`` is the
172default for all created tasks.  If a similar semaphore were to be known
173globally, then the attribute_set parameter would be ``RTEMS_GLOBAL |
174RTEMS_PRIORITY``.
175
176Some combinatinos of these attributes are invalid.  For example, priority
177ordered blocking discipline must be applied to a binary semaphore in order to
178use either the priority inheritance or priority ceiling functionality.  The
179following tree figure illustrates the valid combinations.
180
181.. figure:: ../images/c_user/semaphore_attributes.png
182         :width: 90%
183         :align: center
184         :alt: Semaphore Attributes
185
186.. _Building a SEMAPHORE_OBTAIN Option Set:
187
188Building a SEMAPHORE_OBTAIN Option Set
189--------------------------------------
190
191In general, an option is built by a bitwise OR of the desired option
192components.  The set of valid options for the ``rtems_semaphore_obtain``
193directive are listed in the following table:
194
195.. list-table::
196 :class: rtems-table
197
198 * - ``RTEMS_WAIT``
199   - task will wait for semaphore (default)
200 * - ``RTEMS_NO_WAIT``
201   - task should not wait
202
203Option values are specifically designed to be mutually exclusive, therefore
204bitwise OR and addition operations are equivalent as long as each attribute
205appears exactly once in the component list.  An option listed as a default is
206not required to appear in the list, although it is a good programming practice
207to specify default options.  If all defaults are desired, the option
208``RTEMS_DEFAULT_OPTIONS`` should be specified on this call.
209
210This example demonstrates the option parameter needed to poll for a semaphore.
211The option parameter passed to the ``rtems_semaphore_obtain`` directive should
212be ``RTEMS_NO_WAIT``.
213
214Operations
215==========
216
217.. _Creating a Semaphore:
218
219Creating a Semaphore
220--------------------
221
222The ``rtems_semaphore_create`` directive creates a binary or counting semaphore
223with a user-specified name as well as an initial count.  If a binary semaphore
224is created with a count of zero (0) to indicate that it has been allocated,
225then the task creating the semaphore is considered the current holder of the
226semaphore.  At create time the method for ordering waiting tasks in the
227semaphore's task wait queue (by FIFO or task priority) is specified.
228Additionally, the priority inheritance or priority ceiling algorithm may be
229selected for local, binary semaphores that use the priority task wait queue
230blocking discipline.  If the priority ceiling algorithm is selected, then the
231highest priority of any task which will attempt to obtain this semaphore must
232be specified.  RTEMS allocates a Semaphore Control Block (SMCB) from the SMCB
233free list.  This data structure is used by RTEMS to manage the newly created
234semaphore.  Also, a unique semaphore ID is generated and returned to the
235calling task.
236
237.. _Obtaining Semaphore IDs:
238
239Obtaining Semaphore IDs
240-----------------------
241
242When a semaphore is created, RTEMS generates a unique semaphore ID and assigns
243it to the created semaphore until it is deleted.  The semaphore ID may be
244obtained by either of two methods.  First, as the result of an invocation of
245the ``rtems_semaphore_create`` directive, the semaphore ID is stored in a user
246provided location.  Second, the semaphore ID may be obtained later using the
247``rtems_semaphore_ident`` directive.  The semaphore ID is used by other
248semaphore manager directives to access this semaphore.
249
250.. _Acquiring a Semaphore:
251
252Acquiring a Semaphore
253---------------------
254
255The ``rtems_semaphore_obtain`` directive is used to acquire the
256specified semaphore.  A simplified version of the ``rtems_semaphore_obtain``
257directive can be described as follows:
258
259    If the semaphore's count is greater than zero then decrement the
260    semaphore's count else wait for release of semaphore then return
261    SUCCESSFUL.
262
263When the semaphore cannot be immediately acquired, one of the following
264situations applies:
265
266- By default, the calling task will wait forever to acquire the semaphore.
267
268- Specifying ``RTEMS_NO_WAIT`` forces an immediate return with an error status
269  code.
270
271- Specifying a timeout limits the interval the task will wait before returning
272  with an error status code.
273
274If the task waits to acquire the semaphore, then it is placed in the
275semaphore's task wait queue in either FIFO or task priority order.  If the task
276blocked waiting for a binary semaphore using priority inheritance and the
277task's priority is greater than that of the task currently holding the
278semaphore, then the holding task will inherit the priority of the blocking
279task.  All tasks waiting on a semaphore are returned an error code when the
280semaphore is deleted.
281
282When a task successfully obtains a semaphore using priority ceiling and the
283priority ceiling for this semaphore is greater than that of the holder, then
284the holder's priority will be elevated.
285
286.. _Releasing a Semaphore:
287
288Releasing a Semaphore
289---------------------
290
291The ``rtems_semaphore_release`` directive is used to release the specified
292semaphore.  A simplified version of the ``rtems_semaphore_release`` directive
293can be described as follows:
294
295    If there are no tasks are waiting on this semaphore then increment the
296    semaphore's count else assign semaphore to a waiting task and return
297    SUCCESSFUL.
298
299If this is the outermost release of a binary semaphore that uses priority
300inheritance or priority ceiling and the task does not currently hold any other
301binary semaphores, then the task performing the ``rtems_semaphore_release``
302will have its priority restored to its normal value.
303
304.. _Deleting a Semaphore:
305
306Deleting a Semaphore
307--------------------
308
309The ``rtems_semaphore_delete`` directive removes a semaphore from the system
310and frees its control block.  A semaphore can be deleted by any local task that
311knows the semaphore's ID.  As a result of this directive, all tasks blocked
312waiting to acquire the semaphore will be readied and returned a status code
313which indicates that the semaphore was deleted.  Any subsequent references to
314the semaphore's name and ID are invalid.
315
316Directives
317==========
318
319This section details the semaphore manager's directives.  A subsection is
320dedicated to each of this manager's directives and describes the calling
321sequence, related constants, usage, and status codes.
322
323.. raw:: latex
324
325   \clearpage
326
327.. index:: create a semaphore
328.. index:: rtems_semaphore_create
329
330.. _rtems_semaphore_create:
331
332SEMAPHORE_CREATE - Create a semaphore
333-------------------------------------
334
335
336CALLING SEQUENCE:
337    .. code-block:: c
338
339        rtems_status_code rtems_semaphore_create(
340            rtems_name           name,
341            uint32_t             count,
342            rtems_attribute      attribute_set,
343            rtems_task_priority  priority_ceiling,
344            rtems_id            *id
345        );
346
347DIRECTIVE STATUS CODES:
348    .. list-table::
349     :class: rtems-table
350
351     * - ``RTEMS_SUCCESSFUL``
352       - semaphore created successfully
353     * - ``RTEMS_INVALID_NAME``
354       - invalid semaphore name
355     * - ``RTEMS_INVALID_ADDRESS``
356       - ``id`` is NULL
357     * - ``RTEMS_TOO_MANY``
358       - too many semaphores created
359     * - ``RTEMS_NOT_DEFINED``
360       - invalid attribute set
361     * - ``RTEMS_INVALID_NUMBER``
362       - invalid starting count for binary semaphore
363     * - ``RTEMS_MP_NOT_CONFIGURED``
364       - multiprocessing not configured
365     * - ``RTEMS_TOO_MANY``
366       - too many global objects
367
368DESCRIPTION:
369    This directive creates a semaphore which resides on the local node. The
370    created semaphore has the user-defined name specified in name and the
371    initial count specified in count.  For control and maintenance of the
372    semaphore, RTEMS allocates and initializes a SMCB.  The RTEMS-assigned
373    semaphore id is returned in id.  This semaphore id is used with other
374    semaphore related directives to access the semaphore.
375
376    Specifying PRIORITY in attribute_set causes tasks waiting for a semaphore
377    to be serviced according to task priority.  When FIFO is selected, tasks
378    are serviced in First In-First Out order.
379
380NOTES:
381    This directive will not cause the calling task to be preempted.
382
383    The priority inheritance and priority ceiling algorithms are only supported
384    for local, binary semaphores that use the priority task wait queue blocking
385    discipline.
386
387    The following semaphore attribute constants are defined by RTEMS:
388
389    .. list-table::
390     :class: rtems-table
391
392     * - ``RTEMS_FIFO``
393       - tasks wait by FIFO (default)
394     * - ``RTEMS_PRIORITY``
395       - tasks wait by priority
396     * - ``RTEMS_BINARY_SEMAPHORE``
397       - restrict values to 0 and 1
398     * - ``RTEMS_COUNTING_SEMAPHORE``
399       - no restriction on values (default)
400     * - ``RTEMS_SIMPLE_BINARY_SEMAPHORE``
401       - restrict values to 0 and 1, block on nested access, allow deletion of locked semaphore.
402     * - ``RTEMS_NO_INHERIT_PRIORITY``
403       - do not use priority inheritance (default)
404     * - ``RTEMS_INHERIT_PRIORITY``
405       - use priority inheritance
406     * - ``RTEMS_NO_PRIORITY_CEILING``
407       - do not use priority ceiling (default)
408     * - ``RTEMS_PRIORITY_CEILING``
409       - use priority ceiling
410     * - ``RTEMS_NO_MULTIPROCESSOR_RESOURCE_SHARING``
411       - do not use Multiprocessor Resource Sharing Protocol (default)
412     * - ``RTEMS_MULTIPROCESSOR_RESOURCE_SHARING``
413       - use Multiprocessor Resource Sharing Protocol
414     * - ``RTEMS_LOCAL``
415       - local semaphore (default)
416     * - ``RTEMS_GLOBAL``
417       - global semaphore
418
419    Semaphores should not be made global unless remote tasks must interact with
420    the created semaphore.  This is to avoid the system overhead incurred by
421    the creation of a global semaphore.  When a global semaphore is created,
422    the semaphore's name and id must be transmitted to every node in the system
423    for insertion in the local copy of the global object table.
424
425    *Note*, some combinations of attributes are not valid.  See the earlier
426    discussion on this.
427
428    The total number of global objects, including semaphores, is limited by the
429    maximum_global_objects field in the Configuration Table.
430
431    It is not allowed to create an initially locked MrsP semaphore and the
432    ``RTEMS_INVALID_NUMBER`` status code will be returned in SMP configurations
433    in this case.  This prevents lock order reversal problems with the
434    allocator mutex.
435
436.. raw:: latex
437
438   \clearpage
439
440.. index:: get ID of a semaphore
441.. index:: obtain ID of a semaphore
442.. index:: rtems_semaphore_ident
443
444.. _rtems_semaphore_ident:
445
446SEMAPHORE_IDENT - Get ID of a semaphore
447---------------------------------------
448
449CALLING SEQUENCE:
450    .. code-block:: c
451
452        rtems_status_code rtems_semaphore_ident(
453            rtems_name  name,
454            uint32_t    node,
455            rtems_id   *id
456        );
457
458DIRECTIVE STATUS CODES:
459    .. list-table::
460     :class: rtems-table
461
462     * - ``RTEMS_SUCCESSFUL``
463       - semaphore identified successfully
464     * - ``RTEMS_INVALID_NAME``
465       - semaphore name not found
466     * - ``RTEMS_INVALID_NODE``
467       - invalid node id
468
469DESCRIPTION:
470    This directive obtains the semaphore id associated with the semaphore name.
471    If the semaphore name is not unique, then the semaphore id will match one
472    of the semaphores with that name.  However, this semaphore id is not
473    guaranteed to correspond to the desired semaphore.  The semaphore id is
474    used by other semaphore related directives to access the semaphore.
475
476NOTES:
477    This directive will not cause the running task to be preempted.
478
479    If node is ``RTEMS_SEARCH_ALL_NODES``, all nodes are searched with the
480    local node being searched first.  All other nodes are searched with the
481    lowest numbered node searched first.
482
483    If node is a valid node number which does not represent the local node,
484    then only the semaphores exported by the designated node are searched.
485
486    This directive does not generate activity on remote nodes.  It accesses
487    only the local copy of the global object table.
488
489.. raw:: latex
490
491   \clearpage
492
493.. index:: delete a semaphore
494.. index:: rtems_semaphore_delete
495
496.. _rtems_semaphore_delete:
497
498SEMAPHORE_DELETE - Delete a semaphore
499-------------------------------------
500
501CALLING SEQUENCE:
502    .. code-block:: c
503
504        rtems_status_code rtems_semaphore_delete(
505            rtems_id id
506        );
507
508DIRECTIVE STATUS CODES:
509    .. list-table::
510     :class: rtems-table
511
512     * - ``RTEMS_SUCCESSFUL``
513       - semaphore deleted successfully
514     * - ``RTEMS_INVALID_ID``
515       - invalid semaphore id
516     * - ``RTEMS_RESOURCE_IN_USE``
517       - binary semaphore is in use
518     * - ``RTEMS_ILLEGAL_ON_REMOTE_OBJECT``
519       - cannot delete remote semaphore
520
521DESCRIPTION:
522    This directive deletes the semaphore specified by ``id``.  All tasks
523    blocked waiting to acquire the semaphore will be readied and returned a
524    status code which indicates that the semaphore was deleted.  The SMCB for
525    this semaphore is reclaimed by RTEMS.
526
527NOTES:
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            sc = rtems_semaphore_delete(semaphore_id);
929            assert(sc == RTEMS_SUCCESSFUL);
930            exit(0);
931        }
932
933        #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
934        #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
935        #define CONFIGURE_MAXIMUM_TASKS 1
936        #define CONFIGURE_MAXIMUM_SEMAPHORES 1
937        #define CONFIGURE_MAXIMUM_MRSP_SEMAPHORES 1
938        #define CONFIGURE_MAXIMUM_PROCESSORS 2
939        #define CONFIGURE_SCHEDULER_SIMPLE_SMP
940
941        #include <rtems/scheduler.h>
942
943        RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(a);
944        RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(b);
945
946        #define CONFIGURE_SCHEDULER_CONTROLS \
947                  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(a, SCHED_A), \
948                  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(b, SCHED_B)
949        #define CONFIGURE_SMP_SCHEDULER_ASSIGNMENTS \
950                  RTEMS_SCHEDULER_ASSIGN(0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY), \
951                  RTEMS_SCHEDULER_ASSIGN(1, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY)
952        #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
953        #define CONFIGURE_INIT
954        #include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.