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

5
Last change on this file since e52906b was e52906b, checked in by Sebastian Huber <sebastian.huber@…>, on 01/09/19 at 15:14:06

Simplify SPDX-License-Identifier comment

  • Property mode set to 100644
File size: 34.8 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_MP_NOT_CONFIGURED``
362       - multiprocessing not configured
363     * - ``RTEMS_TOO_MANY``
364       - too many global objects
365
366DESCRIPTION:
367    This directive creates a semaphore which resides on the local node. The
368    created semaphore has the user-defined name specified in name and the
369    initial count specified in count.  For control and maintenance of the
370    semaphore, RTEMS allocates and initializes a SMCB.  The RTEMS-assigned
371    semaphore id is returned in id.  This semaphore id is used with other
372    semaphore related directives to access the semaphore.
373
374    Specifying PRIORITY in attribute_set causes tasks waiting for a semaphore
375    to be serviced according to task priority.  When FIFO is selected, tasks
376    are serviced in First In-First Out order.
377
378NOTES:
379    This directive will not cause the calling task to be preempted.
380
381    The priority inheritance and priority ceiling algorithms are only supported
382    for local, binary semaphores that use the priority task wait queue blocking
383    discipline.
384
385    The following semaphore attribute constants are defined by RTEMS:
386
387    .. list-table::
388     :class: rtems-table
389
390     * - ``RTEMS_FIFO``
391       - tasks wait by FIFO (default)
392     * - ``RTEMS_PRIORITY``
393       - tasks wait by priority
394     * - ``RTEMS_BINARY_SEMAPHORE``
395       - restrict values to 0 and 1
396     * - ``RTEMS_COUNTING_SEMAPHORE``
397       - no restriction on values (default)
398     * - ``RTEMS_SIMPLE_BINARY_SEMAPHORE``
399       - restrict values to 0 and 1, block on nested access, allow deletion of locked semaphore.
400     * - ``RTEMS_NO_INHERIT_PRIORITY``
401       - do not use priority inheritance (default)
402     * - ``RTEMS_INHERIT_PRIORITY``
403       - use priority inheritance
404     * - ``RTEMS_NO_PRIORITY_CEILING``
405       - do not use priority ceiling (default)
406     * - ``RTEMS_PRIORITY_CEILING``
407       - use priority ceiling
408     * - ``RTEMS_NO_MULTIPROCESSOR_RESOURCE_SHARING``
409       - do not use Multiprocessor Resource Sharing Protocol (default)
410     * - ``RTEMS_MULTIPROCESSOR_RESOURCE_SHARING``
411       - use Multiprocessor Resource Sharing Protocol
412     * - ``RTEMS_LOCAL``
413       - local semaphore (default)
414     * - ``RTEMS_GLOBAL``
415       - global semaphore
416
417    Semaphores should not be made global unless remote tasks must interact with
418    the created semaphore.  This is to avoid the system overhead incurred by
419    the creation of a global semaphore.  When a global semaphore is created,
420    the semaphore's name and id must be transmitted to every node in the system
421    for insertion in the local copy of the global object table.
422
423    *Note*, some combinations of attributes are not valid.  See the earlier
424    discussion on this.
425
426    The total number of global objects, including semaphores, is limited by the
427    maximum_global_objects field in the Configuration Table.
428
429    It is not allowed to create an initially locked MrsP semaphore and the
430    ``RTEMS_INVALID_NUMBER`` status code will be returned in SMP configurations
431    in this case.  This prevents lock order reversal problems with the
432    allocator mutex.
433
434.. raw:: latex
435
436   \clearpage
437
438.. index:: get ID of a semaphore
439.. index:: obtain ID of a semaphore
440.. index:: rtems_semaphore_ident
441
442.. _rtems_semaphore_ident:
443
444SEMAPHORE_IDENT - Get ID of a semaphore
445---------------------------------------
446
447CALLING SEQUENCE:
448    .. code-block:: c
449
450        rtems_status_code rtems_semaphore_ident(
451            rtems_name  name,
452            uint32_t    node,
453            rtems_id   *id
454        );
455
456DIRECTIVE STATUS CODES:
457    .. list-table::
458     :class: rtems-table
459
460     * - ``RTEMS_SUCCESSFUL``
461       - semaphore identified successfully
462     * - ``RTEMS_INVALID_NAME``
463       - semaphore name not found
464     * - ``RTEMS_INVALID_NODE``
465       - invalid node id
466
467DESCRIPTION:
468    This directive obtains the semaphore id associated with the semaphore name.
469    If the semaphore name is not unique, then the semaphore id will match one
470    of the semaphores with that name.  However, this semaphore id is not
471    guaranteed to correspond to the desired semaphore.  The semaphore id is
472    used by other semaphore related directives to access the semaphore.
473
474NOTES:
475    This directive will not cause the running task to be preempted.
476
477    If node is ``RTEMS_SEARCH_ALL_NODES``, all nodes are searched with the
478    local node being searched first.  All other nodes are searched with the
479    lowest numbered node searched first.
480
481    If node is a valid node number which does not represent the local node,
482    then only the semaphores exported by the designated node are searched.
483
484    This directive does not generate activity on remote nodes.  It accesses
485    only the local copy of the global object table.
486
487.. raw:: latex
488
489   \clearpage
490
491.. index:: delete a semaphore
492.. index:: rtems_semaphore_delete
493
494.. _rtems_semaphore_delete:
495
496SEMAPHORE_DELETE - Delete a semaphore
497-------------------------------------
498
499CALLING SEQUENCE:
500    .. code-block:: c
501
502        rtems_status_code rtems_semaphore_delete(
503            rtems_id id
504        );
505
506DIRECTIVE STATUS CODES:
507    .. list-table::
508     :class: rtems-table
509
510     * - ``RTEMS_SUCCESSFUL``
511       - semaphore deleted successfully
512     * - ``RTEMS_INVALID_ID``
513       - invalid semaphore id
514     * - ``RTEMS_RESOURCE_IN_USE``
515       - binary semaphore is in use
516     * - ``RTEMS_ILLEGAL_ON_REMOTE_OBJECT``
517       - cannot delete remote semaphore
518
519DESCRIPTION:
520    This directive deletes the semaphore specified by ``id``.  All tasks
521    blocked waiting to acquire the semaphore will be readied and returned a
522    status code which indicates that the semaphore was deleted.  The SMCB for
523    this semaphore is reclaimed by RTEMS.
524
525NOTES:
526    The calling task will be preempted if it is enabled by the task's execution
527    mode and a higher priority local task is waiting on the deleted semaphore.
528    The calling task will NOT be preempted if all of the tasks that are waiting
529    on the semaphore are remote tasks.
530
531    The calling task does not have to be the task that created the semaphore.  Any
532    local task that knows the semaphore id can delete the semaphore.
533
534    When a global semaphore is deleted, the semaphore id must be transmitted to
535    every node in the system for deletion from the local copy of the global
536    object table.
537
538    The semaphore must reside on the local node, even if the semaphore was
539    created with the ``RTEMS_GLOBAL`` option.
540
541    Proxies, used to represent remote tasks, are reclaimed when the semaphore
542    is deleted.
543
544.. raw:: latex
545
546   \clearpage
547
548.. index:: obtain a semaphore
549.. index:: lock a semaphore
550.. index:: rtems_semaphore_obtain
551
552.. _rtems_semaphore_obtain:
553
554SEMAPHORE_OBTAIN - Acquire a semaphore
555--------------------------------------
556
557CALLING SEQUENCE:
558    .. code-block:: c
559
560        rtems_status_code rtems_semaphore_obtain(
561            rtems_id        id,
562            rtems_option    option_set,
563            rtems_interval  timeout
564        );
565
566DIRECTIVE STATUS CODES:
567    .. list-table::
568     :class: rtems-table
569
570     * - ``RTEMS_SUCCESSFUL``
571       - semaphore obtained successfully
572     * - ``RTEMS_UNSATISFIED``
573       - semaphore not available
574     * - ``RTEMS_TIMEOUT``
575       - timed out waiting for semaphore
576     * - ``RTEMS_OBJECT_WAS_DELETED``
577       - semaphore deleted while waiting
578     * - ``RTEMS_INVALID_ID``
579       - invalid semaphore id
580
581DESCRIPTION:
582    This directive acquires the semaphore specified by id.  The ``RTEMS_WAIT``
583    and ``RTEMS_NO_WAIT`` components of the options parameter indicate whether
584    the calling task wants to wait for the semaphore to become available or
585    return immediately if the semaphore is not currently available.  With
586    either ``RTEMS_WAIT`` or ``RTEMS_NO_WAIT``, if the current semaphore count
587    is positive, then it is decremented by one and the semaphore is
588    successfully acquired by returning immediately with a successful return
589    code.
590
591    If the calling task chooses to return immediately and the current semaphore
592    count is zero or negative, then a status code is returned indicating that
593    the semaphore is not available. If the calling task chooses to wait for a
594    semaphore and the current semaphore count is zero or negative, then it is
595    decremented by one and the calling task is placed on the semaphore's wait
596    queue and blocked.  If the semaphore was created with the
597    ``RTEMS_PRIORITY`` attribute, then the calling task is inserted into the
598    queue according to its priority.  However, if the semaphore was created
599    with the ``RTEMS_FIFO`` attribute, then the calling task is placed at the
600    rear of the wait queue.  If the binary semaphore was created with the
601    ``RTEMS_INHERIT_PRIORITY`` attribute, then the priority of the task
602    currently holding the binary semaphore is guaranteed to be greater than or
603    equal to that of the blocking task.  If the binary semaphore was created
604    with the ``RTEMS_PRIORITY_CEILING`` attribute, a task successfully obtains
605    the semaphore, and the priority of that task is greater than the ceiling
606    priority for this semaphore, then the priority of the task obtaining the
607    semaphore is elevated to that of the ceiling.
608
609    The timeout parameter specifies the maximum interval the calling task is
610    willing to be blocked waiting for the semaphore.  If it is set to
611    ``RTEMS_NO_TIMEOUT``, then the calling task will wait forever.  If the
612    semaphore is available or the ``RTEMS_NO_WAIT`` option component is set,
613    then timeout is ignored.
614
615    In case a semaphore is not available, then ``RTEMS_UNSATISFIED`` will be
616    returned.  This happens immediately in case ``RTEMS_NO_WAIT`` is specified,
617    or as a result of another task invoking the ``rtems_semaphore_flush``
618    directive in case ``RTEMS_WAIT`` is specified.
619
620    Deadlock situations are detected for MrsP semaphores and the
621    ``RTEMS_UNSATISFIED`` status code will be returned in SMP configurations in
622    this case.
623
624NOTES:
625    The following semaphore acquisition option constants are defined by RTEMS:
626
627    .. list-table::
628     :class: rtems-table
629
630     * - ``RTEMS_WAIT``
631       - task will wait for semaphore (default)
632     * - ``RTEMS_NO_WAIT``
633       - task should not wait
634
635    Attempting to obtain a global semaphore which does not reside on the local
636    node will generate a request to the remote node to access the semaphore.
637    If the semaphore is not available and ``RTEMS_NO_WAIT`` was not specified,
638    then the task must be blocked until the semaphore is released.  A proxy is
639    allocated on the remote node to represent the task until the semaphore is
640    released.
641
642    A clock tick is required to support the timeout functionality of this
643    directive.
644
645    It is not allowed to obtain a MrsP semaphore more than once by one task at
646    a time (nested access) and the ``RTEMS_UNSATISFIED`` status code will be
647    returned in SMP configurations in this case.
648
649.. raw:: latex
650
651   \clearpage
652
653.. index:: release a semaphore
654.. index:: unlock a semaphore
655.. index:: rtems_semaphore_release
656
657.. _rtems_semaphore_release:
658
659SEMAPHORE_RELEASE - Release a semaphore
660---------------------------------------
661
662CALLING SEQUENCE:
663    .. code-block:: c
664
665        rtems_status_code rtems_semaphore_release(
666            rtems_id id
667        );
668
669DIRECTIVE STATUS CODES:
670    .. list-table::
671     :class: rtems-table
672
673     * - ``RTEMS_SUCCESSFUL``
674       - semaphore released successfully
675     * - ``RTEMS_INVALID_ID``
676       - invalid semaphore id
677     * - ``RTEMS_NOT_OWNER_OF_RESOURCE``
678       - calling task does not own semaphore
679     * - ``RTEMS_INCORRECT_STATE``
680       - invalid unlock order
681
682DESCRIPTION:
683    This directive releases the semaphore specified by id.  The semaphore count
684    is incremented by one.  If the count is zero or negative, then the first
685    task on this semaphore's wait queue is removed and unblocked.  The
686    unblocked task may preempt the running task if the running task's
687    preemption mode is enabled and the unblocked task has a higher priority
688    than the running task.
689
690NOTES:
691    The calling task may be preempted if it causes a higher priority task to be
692    made ready for execution.
693
694    Releasing a global semaphore which does not reside on the local node will
695    generate a request telling the remote node to release the semaphore.
696
697    If the task to be unblocked resides on a different node from the semaphore,
698    then the semaphore allocation is forwarded to the appropriate node, the
699    waiting task is unblocked, and the proxy used to represent the task is
700    reclaimed.
701
702    The outermost release of a local, binary, priority inheritance or priority
703    ceiling semaphore may result in the calling task having its priority
704    lowered.  This will occur if the calling task holds no other binary
705    semaphores and it has inherited a higher priority.
706
707    The MrsP semaphores must be released in the reversed obtain order,
708    otherwise the ``RTEMS_INCORRECT_STATE`` status code will be returned in SMP
709    configurations in this case.
710
711.. raw:: latex
712
713   \clearpage
714
715.. index:: flush a semaphore
716.. index:: unblock all tasks waiting on a semaphore
717.. index:: rtems_semaphore_flush
718
719.. _rtems_semaphore_flush:
720
721SEMAPHORE_FLUSH - Unblock all tasks waiting on a semaphore
722----------------------------------------------------------
723
724CALLING SEQUENCE:
725    .. code-block:: c
726
727        rtems_status_code rtems_semaphore_flush(
728            rtems_id id
729        );
730
731DIRECTIVE STATUS CODES:
732    .. list-table::
733     :class: rtems-table
734
735     * - ``RTEMS_SUCCESSFUL``
736       - semaphore released successfully
737     * - ``RTEMS_INVALID_ID``
738       - invalid semaphore id
739     * - ``RTEMS_NOT_DEFINED``
740       - operation not defined for the protocol of the semaphore
741     * - ``RTEMS_ILLEGAL_ON_REMOTE_OBJECT``
742       - not supported for remote semaphores
743
744DESCRIPTION:
745    This directive unblocks all tasks waiting on the semaphore specified by id.
746    Since there are tasks blocked on the semaphore, the semaphore's count is
747    not changed by this directive and thus is zero before and after this
748    directive is executed.  Tasks which are unblocked as the result of this
749    directive will return from the ``rtems_semaphore_obtain`` directive with a
750    status code of ``RTEMS_UNSATISFIED`` to indicate that the semaphore was not
751    obtained.
752
753    This directive may unblock any number of tasks.  Any of the unblocked tasks
754    may preempt the running task if the running task's preemption mode is
755    enabled and an unblocked task has a higher priority than the running task.
756
757NOTES:
758    The calling task may be preempted if it causes a higher priority task to be
759    made ready for execution.
760
761    If the task to be unblocked resides on a different node from the semaphore,
762    then the waiting task is unblocked, and the proxy used to represent the
763    task is reclaimed.
764
765    It is not allowed to flush a MrsP semaphore and the ``RTEMS_NOT_DEFINED``
766    status code will be returned in SMP configurations in this case.
767
768    Using the ``rtems_semaphore_flush`` directive for condition synchronization
769    in concert with another semaphore may be subject to the lost wake-up
770    problem.  The following attempt to implement a condition variable is
771    broken.
772
773    .. code-block:: c
774
775        #include <rtems.h>
776        #include <assert.h>
777
778        void cnd_wait( rtems_id cnd, rtems_id mtx )
779        {
780          rtems_status_code sc;
781
782          sc = rtems_semaphore_release( mtx );
783          assert( sc == RTEMS_SUCCESSFUL );
784
785          /*
786           * Here, a higher priority task may run and satisfy the condition. We
787           * may never wake up from the next semaphore obtain.
788           */
789
790          sc = rtems_semaphore_obtain( cnd, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
791          assert( sc == RTEMS_UNSATISFIED );
792
793          sc = rtems_semaphore_obtain( mtx, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
794          assert( sc == RTEMS_SUCCESSFUL );
795        }
796
797        void cnd_broadcast( rtems_id cnd )
798        {
799          rtems_status_code sc;
800
801          sc = rtems_semaphore_flush( cnd );
802          assert( sc == RTEMS_SUCCESSFUL );
803        }
804
805    For barrier synchronization, the :ref:`barrier_manager` offers a cleaner
806    alternative to using the `rtems_semaphore_flush` directive.  Unlike POSIX
807    barriers, they have a manual release option.
808
809.. raw:: latex
810
811   \clearpage
812
813.. index:: set priority by scheduler for a semaphore
814.. index:: rtems_semaphore_set_priority
815
816.. _rtems_semaphore_set_priority:
817
818SEMAPHORE_SET_PRIORITY - Set priority by scheduler for a semaphore
819------------------------------------------------------------------
820
821CALLING SEQUENCE:
822    .. code-block:: c
823
824        rtems_status_code rtems_semaphore_set_priority(
825            rtems_id             semaphore_id,
826            rtems_id             scheduler_id,
827            rtems_task_priority  new_priority,
828            rtems_task_priority *old_priority
829        );
830
831DIRECTIVE STATUS CODES:
832    .. list-table::
833     :class: rtems-table
834
835     * - ``RTEMS_SUCCESSFUL``
836       - successful operation
837     * - ``RTEMS_INVALID_ID``
838       - invalid semaphore or scheduler id
839     * - ``RTEMS_INVALID_ADDRESS``
840       - ``old_priority`` is NULL
841     * - ``RTEMS_INVALID_PRIORITY``
842       - invalid new priority value
843     * - ``RTEMS_NOT_DEFINED``
844       - operation not defined for the protocol ofthe semaphore
845     * - ``RTEMS_ILLEGAL_ON_REMOTE_OBJECT``
846       - not supported for remote semaphores
847
848DESCRIPTION:
849    This directive sets the priority value with respect to the specified
850    scheduler of a semaphore.
851
852    The special priority value ``RTEMS_CURRENT_PRIORITY`` can be used to get
853    the current priority value without changing it.
854
855    The interpretation of the priority value depends on the protocol of the
856    semaphore object.
857
858    - The Multiprocessor Resource Sharing Protocol needs a ceiling priority per
859      scheduler instance.  This operation can be used to specify these priority
860      values.
861
862    - For the Priority Ceiling Protocol the ceiling priority is used with this
863      operation.
864
865    - For other protocols this operation is not defined.
866
867EXAMPLE:
868    .. code-block:: c
869        :linenos:
870
871        #include <assert.h>
872        #include <stdlib.h>
873        #include <rtems.h>
874
875        #define SCHED_A rtems_build_name(' ', ' ', ' ', 'A')
876        #define SCHED_B rtems_build_name(' ', ' ', ' ', 'B')
877
878        static void Init(rtems_task_argument arg)
879        {
880            rtems_status_code   sc;
881            rtems_id            semaphore_id;
882            rtems_id            scheduler_a_id;
883            rtems_id            scheduler_b_id;
884            rtems_task_priority prio;
885
886            /* Get the scheduler identifiers */
887            sc = rtems_scheduler_ident(SCHED_A, &scheduler_a_id);
888            assert(sc == RTEMS_SUCCESSFUL);
889            sc = rtems_scheduler_ident(SCHED_B, &scheduler_b_id);
890            assert(sc == RTEMS_SUCCESSFUL);
891
892            /* Create a MrsP semaphore object */
893            sc = rtems_semaphore_create(
894                rtems_build_name('M', 'R', 'S', 'P'),
895                1,
896                RTEMS_MULTIPROCESSOR_RESOURCE_SHARING | RTEMS_BINARY_SEMAPHORE,
897                1,
898                &semaphore_id
899            );
900            assert(sc == RTEMS_SUCCESSFUL);
901
902            /*
903             * The ceiling priority values per scheduler are equal to the value specified
904             * for object creation.
905             */
906            prio = RTEMS_CURRENT_PRIORITY;
907            sc = rtems_semaphore_set_priority(semaphore_id, scheduler_a_id, prio, &prio);
908            assert(sc == RTEMS_SUCCESSFUL);
909            assert(prio == 1);
910
911            /* Check the old value and set a new ceiling priority for scheduler B */
912            prio = 2;
913            sc = rtems_semaphore_set_priority(semaphore_id, scheduler_b_id, prio, &prio);
914            assert(sc == RTEMS_SUCCESSFUL);
915            assert(prio == 1);
916
917            /* Check the ceiling priority values */
918            prio = RTEMS_CURRENT_PRIORITY;
919            sc = rtems_semaphore_set_priority(semaphore_id, scheduler_a_id, prio, &prio);
920            assert(sc == RTEMS_SUCCESSFUL);
921            assert(prio == 1);
922            prio = RTEMS_CURRENT_PRIORITY;
923            sc = rtems_semaphore_set_priority(semaphore_id, scheduler_b_id, prio, &prio);
924            assert(sc == RTEMS_SUCCESSFUL);
925            assert(prio == 2);
926            sc = rtems_semaphore_delete(semaphore_id);
927            assert(sc == RTEMS_SUCCESSFUL);
928            exit(0);
929        }
930
931        #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
932        #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
933        #define CONFIGURE_MAXIMUM_TASKS 1
934        #define CONFIGURE_MAXIMUM_SEMAPHORES 1
935        #define CONFIGURE_MAXIMUM_MRSP_SEMAPHORES 1
936        #define CONFIGURE_MAXIMUM_PROCESSORS 2
937        #define CONFIGURE_SCHEDULER_SIMPLE_SMP
938
939        #include <rtems/scheduler.h>
940
941        RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(a);
942        RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(b);
943
944        #define CONFIGURE_SCHEDULER_CONTROLS \
945                  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(a, SCHED_A), \
946                  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(b, SCHED_B)
947        #define CONFIGURE_SMP_SCHEDULER_ASSIGNMENTS \
948                  RTEMS_SCHEDULER_ASSIGN(0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY), \
949                  RTEMS_SCHEDULER_ASSIGN(1, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY)
950        #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
951        #define CONFIGURE_INIT
952        #include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.