source: rtems-docs/c_user/semaphore_manager.rst @ 170418a

4.115am
Last change on this file since 170418a was 170418a, checked in by Amar Takhar <verm@…>, on 05/18/16 at 17:47:42

Move images to a common directory.

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