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

5
Last change on this file since 31157bc was 31157bc, checked in by Sebastian Huber <sebastian.huber@…>, on 01/23/17 at 12:44:43

c-user: Clarify simple binary semaphore release

Close #2725.

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