source: rtems-docs/c_user/semaphore_manager.rst @ fd6dc8c8

4.115
Last change on this file since fd6dc8c8 was fd6dc8c8, checked in by Amar Takhar <amar@…>, on 01/18/16 at 00:19:43

Split document into seperate files by section.

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