source: rtems-docs/c_user/semaphore_manager.rst @ 36def91

4.115
Last change on this file since 36def91 was 36def91, checked in by Joel Sherrill <joel@…>, on 10/28/16 at 00:47:07

rtems-docs: Fix many unnecessary back slashes

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