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

4.115
Last change on this file since f02e872 was f02e872, checked in by Chris Johns <chrisj@…>, on 02/17/16 at 23:32:05

Fix the double quotes.

  • Property mode set to 100644
File size: 35.8 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.. code:: c
245
246    Not available in ASCII representation
247
248Building a SEMAPHORE_OBTAIN Option Set
249--------------------------------------
250
251In general, an option is built by a bitwise OR of the desired option
252components.  The set of valid options for the ``rtems_semaphore_obtain``
253directive are listed in the following table:
254
255.. list-table::
256 :class: rtems-table
257
258 * - ``RTEMS_WAIT``
259   - task will wait for semaphore (default)
260 * - ``RTEMS_NO_WAIT``
261   - task should not wait
262
263Option values are specifically designed to be mutually exclusive, therefore
264bitwise OR and addition operations are equivalent as long as each attribute
265appears exactly once in the component list.  An option listed as a default is
266not required to appear in the list, although it is a good programming practice
267to specify default options.  If all defaults are desired, the option
268``RTEMS_DEFAULT_OPTIONS`` should be specified on this call.
269
270This example demonstrates the option parameter needed to poll for a semaphore.
271The option parameter passed to the ``rtems_semaphore_obtain`` directive should
272be ``RTEMS_NO_WAIT``.
273
274Operations
275==========
276
277Creating a Semaphore
278--------------------
279
280The ``rtems_semaphore_create`` directive creates a binary or counting semaphore
281with a user-specified name as well as an initial count.  If a binary semaphore
282is created with a count of zero (0) to indicate that it has been allocated,
283then the task creating the semaphore is considered the current holder of the
284semaphore.  At create time the method for ordering waiting tasks in the
285semaphore's task wait queue (by FIFO or task priority) is specified.
286Additionally, the priority inheritance or priority ceiling algorithm may be
287selected for local, binary semaphores that use the priority task wait queue
288blocking discipline.  If the priority ceiling algorithm is selected, then the
289highest priority of any task which will attempt to obtain this semaphore must
290be specified.  RTEMS allocates a Semaphore Control Block (SMCB) from the SMCB
291free list.  This data structure is used by RTEMS to manage the newly created
292semaphore.  Also, a unique semaphore ID is generated and returned to the
293calling task.
294
295Obtaining Semaphore IDs
296-----------------------
297
298When a semaphore is created, RTEMS generates a unique semaphore ID and assigns
299it to the created semaphore until it is deleted.  The semaphore ID may be
300obtained by either of two methods.  First, as the result of an invocation of
301the ``rtems_semaphore_create`` directive, the semaphore ID is stored in a user
302provided location.  Second, the semaphore ID may be obtained later using the
303``rtems_semaphore_ident`` directive.  The semaphore ID is used by other
304semaphore manager directives to access this semaphore.
305
306Acquiring a Semaphore
307---------------------
308
309The ``rtems_semaphore_obtain`` directive is used to acquire the
310specified semaphore.  A simplified version of the ``rtems_semaphore_obtain``
311directive can be described as follows:
312
313    If the semaphore's count is greater than zero then decrement the
314    semaphore's count else wait for release of semaphore then return
315    SUCCESSFUL.
316
317When the semaphore cannot be immediately acquired, one of the following
318situations applies:
319
320- By default, the calling task will wait forever to acquire the semaphore.
321
322- Specifying ``RTEMS_NO_WAIT`` forces an immediate return with an error status
323  code.
324
325- Specifying a timeout limits the interval the task will wait before returning
326  with an error status code.
327
328If the task waits to acquire the semaphore, then it is placed in the
329semaphore's task wait queue in either FIFO or task priority order.  If the task
330blocked waiting for a binary semaphore using priority inheritance and the
331task's priority is greater than that of the task currently holding the
332semaphore, then the holding task will inherit the priority of the blocking
333task.  All tasks waiting on a semaphore are returned an error code when the
334semaphore is deleted.
335
336When a task successfully obtains a semaphore using priority ceiling and the
337priority ceiling for this semaphore is greater than that of the holder, then
338the holder's priority will be elevated.
339
340Releasing a Semaphore
341---------------------
342
343The ``rtems_semaphore_release`` directive is used to release the specified
344semaphore.  A simplified version of the ``rtems_semaphore_release`` directive
345can be described as follows:
346
347    If there sre no tasks are waiting on this semaphore then increment the
348    semaphore's count else assign semaphore to a waiting task and return
349    SUCCESSFUL.
350
351If this is the outermost release of a binary semaphore that uses priority
352inheritance or priority ceiling and the task does not currently hold any other
353binary semaphores, then the task performing the ``rtems_semaphore_release``
354will have its priority restored to its normal value.
355
356Deleting a Semaphore
357--------------------
358
359The ``rtems_semaphore_delete`` directive removes a semaphore from the system
360and frees its control block.  A semaphore can be deleted by any local task that
361knows the semaphore's ID.  As a result of this directive, all tasks blocked
362waiting to acquire the semaphore will be readied and returned a status code
363which indicates that the semaphore was deleted.  Any subsequent references to
364the semaphore's name and ID are invalid.
365
366Directives
367==========
368
369This section details the semaphore manager's directives.  A subsection is
370dedicated to each of this manager's directives and describes the calling
371sequence, related constants, usage, and status codes.
372
373.. _rtems_semaphore_create:
374
375SEMAPHORE_CREATE - Create a semaphore
376-------------------------------------
377.. index:: create a semaphore
378
379**CALLING SEQUENCE:**
380
381.. index:: rtems_semaphore_create
382
383.. code:: c
384
385    rtems_status_code rtems_semaphore_create(
386        rtems_name           name,
387        uint32_t             count,
388        rtems_attribute      attribute_set,
389        rtems_task_priority  priority_ceiling,
390        rtems_id            *id
391    );
392
393**DIRECTIVE STATUS CODES:**
394
395.. list-table::
396 :class: rtems-table
397
398 * - ``RTEMS_SUCCESSFUL``
399   - semaphore created successfully
400 * - ``RTEMS_INVALID_NAME``
401   - invalid semaphore name
402 * - ``RTEMS_INVALID_ADDRESS``
403   - ``id`` is NULL
404 * - ``RTEMS_TOO_MANY``
405   - too many semaphores created
406 * - ``RTEMS_NOT_DEFINED``
407   - invalid attribute set
408 * - ``RTEMS_INVALID_NUMBER``
409   - invalid starting count for binary semaphore
410 * - ``RTEMS_MP_NOT_CONFIGURED``
411   - multiprocessing not configured
412 * - ``RTEMS_TOO_MANY``
413   - too many global objects
414
415**DESCRIPTION:**
416
417This directive creates a semaphore which resides on the local node. The created
418semaphore has the user-defined name specified in name and the initial count
419specified in count.  For control and maintenance of the semaphore, RTEMS
420allocates and initializes a SMCB.  The RTEMS-assigned semaphore id is returned
421in id.  This semaphore id is used with other semaphore related directives to
422access the semaphore.
423
424Specifying PRIORITY in attribute_set causes tasks waiting for a semaphore to be
425serviced according to task priority.  When FIFO is selected, tasks are serviced
426in First In-First Out order.
427
428**NOTES:**
429
430This directive will not cause the calling task to be preempted.
431
432The priority inheritance and priority ceiling algorithms are only supported for
433local, binary semaphores that use the priority task wait queue blocking
434discipline.
435
436The following semaphore attribute constants are
437defined by RTEMS:
438
439.. list-table::
440 :class: rtems-table
441
442 * - ``RTEMS_FIFO``
443   - tasks wait by FIFO (default)
444 * - ``RTEMS_PRIORITY``
445   - tasks wait by priority
446 * - ``RTEMS_BINARY_SEMAPHORE``
447   - restrict values to 0 and 1
448 * - ``RTEMS_COUNTING_SEMAPHORE``
449   - no restriction on values (default)
450 * - ``RTEMS_SIMPLE_BINARY_SEMAPHORE``
451   - restrict values to 0 and 1, block on nested access, allow deletion of locked semaphore.
452 * - ``RTEMS_NO_INHERIT_PRIORITY``
453   - do not use priority inheritance (default)
454 * - ``RTEMS_INHERIT_PRIORITY``
455   - use priority inheritance
456 * - ``RTEMS_NO_PRIORITY_CEILING``
457   - do not use priority ceiling (default)
458 * - ``RTEMS_PRIORITY_CEILING``
459   - use priority ceiling
460 * - ``RTEMS_NO_MULTIPROCESSOR_RESOURCE_SHARING``
461   - do not use Multiprocessor Resource Sharing Protocol (default)
462 * - ``RTEMS_MULTIPROCESSOR_RESOURCE_SHARING``
463   - use Multiprocessor Resource Sharing Protocol
464 * - ``RTEMS_LOCAL``
465   - local semaphore (default)
466 * - ``RTEMS_GLOBAL``
467   - global semaphore
468
469Semaphores should not be made global unless remote tasks must interact with the
470created semaphore.  This is to avoid the system overhead incurred by the
471creation of a global semaphore.  When a global semaphore is created, the
472semaphore's name and id must be transmitted to every node in the system for
473insertion in the local copy of the global object table.
474
475Note that some combinations of attributes are not valid.  See the earlier
476discussion on this.
477
478The total number of global objects, including semaphores, is limited by the
479maximum_global_objects field in the Configuration Table.
480
481It is not allowed to create an initially locked MrsP semaphore and the
482``RTEMS_INVALID_NUMBER`` status code will be returned on SMP configurations in
483this case.  This prevents lock order reversal problems with the allocator
484mutex.
485
486.. _rtems_semaphore_ident:
487
488SEMAPHORE_IDENT - Get ID of a semaphore
489---------------------------------------
490.. index:: get ID of a semaphore
491.. index:: obtain ID of a semaphore
492
493**CALLING SEQUENCE:**
494
495.. index:: rtems_semaphore_ident
496
497.. code:: c
498
499    rtems_status_code rtems_semaphore_ident(
500        rtems_name  name,
501        uint32_t    node,
502        rtems_id   *id
503    );
504
505**DIRECTIVE STATUS CODES:**
506
507.. list-table::
508 :class: rtems-table
509
510 * - ``RTEMS_SUCCESSFUL``
511   - semaphore identified successfully
512 * - ``RTEMS_INVALID_NAME``
513   - semaphore name not found
514 * - ``RTEMS_INVALID_NODE``
515   - invalid node id
516
517**DESCRIPTION:**
518
519This directive obtains the semaphore id associated with the semaphore name.  If
520the semaphore name is not unique, then the semaphore id will match one of the
521semaphores with that name.  However, this semaphore id is not guaranteed to
522correspond to the desired semaphore.  The semaphore id is used by other
523semaphore related directives to access the semaphore.
524
525**NOTES:**
526
527This directive will not cause the running task to be preempted.
528
529If node is ``RTEMS_SEARCH_ALL_NODES``, all nodes are searched with the local
530node being searched first.  All other nodes are searched with the lowest
531numbered node searched first.
532
533If node is a valid node number which does not represent the local node, then
534only the semaphores exported by the designated node are searched.
535
536This directive does not generate activity on remote nodes.  It accesses only
537the local copy of the global object table.
538
539.. _rtems_semaphore_delete:
540
541SEMAPHORE_DELETE - Delete a semaphore
542-------------------------------------
543.. index:: delete a semaphore
544
545**CALLING SEQUENCE:**
546
547.. index:: rtems_semaphore_delete
548
549.. code:: c
550
551    rtems_status_code rtems_semaphore_delete(
552    rtems_id id
553    );
554
555**DIRECTIVE STATUS CODES:**
556
557.. list-table::
558 :class: rtems-table
559
560 * - ``RTEMS_SUCCESSFUL``
561   - semaphore deleted successfully
562 * - ``RTEMS_INVALID_ID``
563   - invalid semaphore id
564 * - ``RTEMS_RESOURCE_IN_USE``
565   - binary semaphore is in use
566 * - ``RTEMS_ILLEGAL_ON_REMOTE_OBJECT``
567   - cannot delete remote semaphore
568
569**DESCRIPTION:**
570
571This directive deletes the semaphore specified by ``id``.  All tasks blocked
572waiting to acquire the semaphore will be readied and returned a status code
573which indicates that the semaphore was deleted.  The SMCB for this semaphore is
574reclaimed by RTEMS.
575
576**NOTES:**
577
578The calling task will be preempted if it is enabled by the task's execution
579mode and a higher priority local task is waiting on the deleted semaphore.  The
580calling task will NOT be preempted if all of the tasks that are waiting on the
581semaphore are remote tasks.
582
583The calling task does not have to be the task that created the semaphore.  Any
584local task that knows the semaphore id can delete the semaphore.
585
586When a global semaphore is deleted, the semaphore id must be transmitted to
587every node in the system for deletion from the local copy of the global object
588table.
589
590The semaphore must reside on the local node, even if the semaphore was created
591with the ``RTEMS_GLOBAL`` option.
592
593Proxies, used to represent remote tasks, are reclaimed when the semaphore is
594deleted.
595
596.. _rtems_semaphore_obtain:
597
598SEMAPHORE_OBTAIN - Acquire a semaphore
599--------------------------------------
600.. index:: obtain a semaphore
601.. index:: lock a semaphore
602
603**CALLING SEQUENCE:**
604
605.. index:: rtems_semaphore_obtain
606
607.. code:: c
608
609    rtems_status_code rtems_semaphore_obtain(
610        rtems_id        id,
611        rtems_option    option_set,
612        rtems_interval  timeout
613    );
614
615**DIRECTIVE STATUS CODES:**
616
617.. list-table::
618 :class: rtems-table
619
620 * - ``RTEMS_SUCCESSFUL``
621   - semaphore obtained successfully
622 * - ``RTEMS_UNSATISFIED``
623   - semaphore not available
624 * - ``RTEMS_TIMEOUT``
625   - timed out waiting for semaphore
626 * - ``RTEMS_OBJECT_WAS_DELETED``
627   - semaphore deleted while waiting
628 * - ``RTEMS_INVALID_ID``
629   - invalid semaphore id
630
631**DESCRIPTION:**
632
633This directive acquires the semaphore specified by id.  The ``RTEMS_WAIT`` and
634``RTEMS_NO_WAIT`` components of the options parameter indicate whether the
635calling task wants to wait for the semaphore to become available or return
636immediately if the semaphore is not currently available.  With either
637``RTEMS_WAIT`` or ``RTEMS_NO_WAIT``, if the current semaphore count is
638positive, then it is decremented by one and the semaphore is successfully
639acquired by returning immediately with a successful return code.
640
641If the calling task chooses to return immediately and the current semaphore
642count is zero or negative, then a status code is returned indicating that the
643semaphore is not available. If the calling task chooses to wait for a semaphore
644and the current semaphore count is zero or negative, then it is decremented by
645one and the calling task is placed on the semaphore's wait queue and blocked.
646If the semaphore was created with the ``RTEMS_PRIORITY`` attribute, then the
647calling task is inserted into the queue according to its priority.  However, if
648the semaphore was created with the ``RTEMS_FIFO`` attribute, then the calling
649task is placed at the rear of the wait queue.  If the binary semaphore was
650created with the ``RTEMS_INHERIT_PRIORITY`` attribute, then the priority of the
651task currently holding the binary semaphore is guaranteed to be greater than or
652equal to that of the blocking task.  If the binary semaphore was created with
653the ``RTEMS_PRIORITY_CEILING`` attribute, a task successfully obtains the
654semaphore, and the priority of that task is greater than the ceiling priority
655for this semaphore, then the priority of the task obtaining the semaphore is
656elevated to that of the ceiling.
657
658The timeout parameter specifies the maximum interval the calling task is
659willing to be blocked waiting for the semaphore.  If it is set to
660``RTEMS_NO_TIMEOUT``, then the calling task will wait forever.  If the
661semaphore is available or the ``RTEMS_NO_WAIT`` option component is set, then
662timeout is ignored.
663
664Deadlock situations are detected for MrsP semaphores and the
665``RTEMS_UNSATISFIED`` status code will be returned on SMP configurations in
666this case.
667
668**NOTES:**
669
670The following semaphore acquisition option constants are defined by RTEMS:
671
672.. list-table::
673 :class: rtems-table
674
675 * - ``RTEMS_WAIT``
676   - task will wait for semaphore (default)
677 * - - ``RTEMS_NO_WAIT``
678   - task should not wait
679
680Attempting to obtain a global semaphore which does not reside on the local node
681will generate a request to the remote node to access the semaphore.  If the
682semaphore is not available and ``RTEMS_NO_WAIT`` was not specified, then the
683task must be blocked until the semaphore is released.  A proxy is allocated on
684the remote node to represent the task until the semaphore is released.
685
686A clock tick is required to support the timeout functionality of this
687directive.
688
689It is not allowed to obtain a MrsP semaphore more than once by one task at a
690time (nested access) and the ``RTEMS_UNSATISFIED`` status code will be returned
691on SMP configurations in this case.
692
693.. _rtems_semaphore_release:
694
695SEMAPHORE_RELEASE - Release a semaphore
696---------------------------------------
697.. index:: release a semaphore
698.. index:: unlock a semaphore
699
700**CALLING SEQUENCE:**
701
702.. index:: rtems_semaphore_release
703
704.. code:: c
705
706    rtems_status_code rtems_semaphore_release(
707        rtems_id id
708    );
709
710**DIRECTIVE STATUS CODES:**
711
712.. list-table::
713 :class: rtems-table
714
715 * - ``RTEMS_SUCCESSFUL``
716   - semaphore released successfully
717 * - ``RTEMS_INVALID_ID``
718   - invalid semaphore id
719 * - ``RTEMS_NOT_OWNER_OF_RESOURCE``
720   - calling task does not own semaphore
721 * - ``RTEMS_INCORRECT_STATE``
722   - invalid unlock order
723
724**DESCRIPTION:**
725
726This directive releases the semaphore specified by id.  The semaphore count is
727incremented by one.  If the count is zero or negative, then the first task on
728this semaphore's wait queue is removed and unblocked.  The unblocked task may
729preempt the running task if the running task's preemption mode is enabled and
730the unblocked task has a higher priority than the running task.
731
732**NOTES:**
733
734The calling task may be preempted if it causes a higher priority task to be
735made ready for execution.
736
737Releasing a global semaphore which does not reside on the local node will
738generate a request telling the remote node to release the semaphore.
739
740If the task to be unblocked resides on a different node from the semaphore,
741then the semaphore allocation is forwarded to the appropriate node, the waiting
742task is unblocked, and the proxy used to represent the task is reclaimed.
743
744The outermost release of a local, binary, priority inheritance or priority
745ceiling semaphore may result in the calling task having its priority lowered.
746This will occur if the calling task holds no other binary semaphores and it has
747inherited a higher priority.
748
749The MrsP semaphores must be released in the reversed obtain order, otherwise
750the ``RTEMS_INCORRECT_STATE`` status code will be returned on SMP
751configurations in this case.
752
753.. _rtems_semaphore_flush:
754
755SEMAPHORE_FLUSH - Unblock all tasks waiting on a semaphore
756----------------------------------------------------------
757.. index:: flush a semaphore
758.. index:: unblock all tasks waiting on a semaphore
759
760**CALLING SEQUENCE:**
761
762.. index:: rtems_semaphore_flush
763
764.. code:: c
765
766    rtems_status_code rtems_semaphore_flush(
767        rtems_id id
768    );
769
770**DIRECTIVE STATUS CODES:**
771
772.. list-table::
773 :class: rtems-table
774
775 * - ``RTEMS_SUCCESSFUL``
776   - semaphore released successfully
777 * - ``RTEMS_INVALID_ID``
778   - invalid semaphore id
779 * - ``RTEMS_NOT_DEFINED``
780   - operation not defined for the protocol ofthe semaphore
781 * - ``RTEMS_ILLEGAL_ON_REMOTE_OBJECT``
782   - not supported for remote semaphores
783
784**DESCRIPTION:**
785
786This directive unblocks all tasks waiting on the semaphore specified by id.
787Since there are tasks blocked on the semaphore, the semaphore's count is not
788changed by this directive and thus is zero before and after this directive is
789executed.  Tasks which are unblocked as the result of this directive will
790return from the ``rtems_semaphore_obtain`` directive with a status code of
791``RTEMS_UNSATISFIED`` to indicate that the semaphore was not obtained.
792
793This directive may unblock any number of tasks.  Any of the unblocked tasks may
794preempt the running task if the running task's preemption mode is enabled and
795an unblocked task has a higher priority than the running task.
796
797**NOTES:**
798
799The calling task may be preempted if it causes a higher priority task to be
800made ready for execution.
801
802If the task to be unblocked resides on a different node from the semaphore,
803then the waiting task is unblocked, and the proxy used to represent the task is
804reclaimed.
805
806It is not allowed to flush a MrsP semaphore and the ``RTEMS_NOT_DEFINED``
807status code will be returned on SMP configurations in this case.
808
809.. _rtems_semaphore_set_priority:
810
811SEMAPHORE_SET_PRIORITY - Set priority by scheduler for a semaphore
812------------------------------------------------------------------
813.. index:: set priority by scheduler for a semaphore
814
815**CALLING SEQUENCE:**
816
817.. index:: rtems_semaphore_set_priority
818
819.. code:: c
820
821    rtems_status_code rtems_semaphore_set_priority(
822        rtems_id             semaphore_id,
823        rtems_id             scheduler_id,
824        rtems_task_priority  new_priority,
825        rtems_task_priority *old_priority
826    );
827
828**DIRECTIVE STATUS CODES:**
829
830.. list-table::
831 :class: rtems-table
832
833 * - ``RTEMS_SUCCESSFUL``
834   - successful operation
835 * - ``RTEMS_INVALID_ID``
836   - invalid semaphore or scheduler id
837 * - ``RTEMS_INVALID_ADDRESS``
838   - ``old_priority`` is NULL
839 * - ``RTEMS_INVALID_PRIORITY``
840   - invalid new priority value
841 * - ``RTEMS_NOT_DEFINED``
842   - operation not defined for the protocol ofthe semaphore
843 * - ``RTEMS_ILLEGAL_ON_REMOTE_OBJECT``
844   - not supported for remote semaphores
845
846**DESCRIPTION:**
847
848This directive sets the priority value with respect to the specified scheduler
849of a semaphore.
850
851The special priority value ``RTEMS_CURRENT_PRIORITY`` can be used to get the
852current priority value without changing it.
853
854The interpretation of the priority value depends on the protocol of the
855semaphore object.
856
857- The Multiprocessor Resource Sharing Protocol needs a ceiling priority per
858  scheduler instance.  This operation can be used to specify these priority
859  values.
860
861- For the Priority Ceiling Protocol the ceiling priority is used with this
862  operation.
863
864- For other protocols this operation is not defined.
865
866**EXAMPLE:**
867
868.. code-block:: c
869    :linenos:
870
871    #include <assert.h>
872    #include <stdlib.h>
873    #include <rtems.h>
874
875    #define SCHED_A rtems_build_name(' ', ' ', ' ', 'A')
876    #define SCHED_B rtems_build_name(' ', ' ', ' ', 'B')
877
878    static void Init(rtems_task_argument arg)
879    {
880        rtems_status_code   sc;
881        rtems_id            semaphore_id;
882        rtems_id            scheduler_a_id;
883        rtems_id            scheduler_b_id;
884        rtems_task_priority prio;
885
886        /* Get the scheduler identifiers */
887        sc = rtems_scheduler_ident(SCHED_A, &scheduler_a_id);
888        assert(sc == RTEMS_SUCCESSFUL);
889        sc = rtems_scheduler_ident(SCHED_B, &scheduler_b_id);
890        assert(sc == RTEMS_SUCCESSFUL);
891
892        /* Create a MrsP semaphore object */
893        sc = rtems_semaphore_create(
894            rtems_build_name('M', 'R', 'S', 'P'),
895            1,
896            RTEMS_MULTIPROCESSOR_RESOURCE_SHARING | RTEMS_BINARY_SEMAPHORE,
897            1,
898            &semaphore_id
899        );
900        assert(sc == RTEMS_SUCCESSFUL);
901
902        /*
903         * The ceiling priority values per scheduler are equal to the value specified
904         * for object creation.
905         */
906        prio = RTEMS_CURRENT_PRIORITY;
907        sc = rtems_semaphore_set_priority(semaphore_id, scheduler_a_id, prio, &prio);
908        assert(sc == RTEMS_SUCCESSFUL);
909        assert(prio == 1);
910
911        /* Check the old value and set a new ceiling priority for scheduler B */
912        prio = 2;
913        sc = rtems_semaphore_set_priority(semaphore_id, scheduler_b_id, prio, &prio);
914        assert(sc == RTEMS_SUCCESSFUL);
915        assert(prio == 1);
916
917        /* Check the ceiling priority values \*/
918        prio = RTEMS_CURRENT_PRIORITY;
919        sc = rtems_semaphore_set_priority(semaphore_id, scheduler_a_id, prio, &prio);
920        assert(sc == RTEMS_SUCCESSFUL);
921        assert(prio == 1);
922        prio = RTEMS_CURRENT_PRIORITY;
923        sc = rtems_semaphore_set_priority(semaphore_id, scheduler_b_id, prio, &prio);
924        assert(sc == RTEMS_SUCCESSFUL);
925        assert(prio == 2);
926        sc = rtems_semaphore_delete(semaphore_id);
927        assert(sc == RTEMS_SUCCESSFUL);
928        exit(0);
929    }
930
931    #define CONFIGURE_SMP_APPLICATION
932    #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
933    #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
934    #define CONFIGURE_MAXIMUM_TASKS 1
935    #define CONFIGURE_MAXIMUM_SEMAPHORES 1
936    #define CONFIGURE_MAXIMUM_MRSP_SEMAPHORES 1
937    #define CONFIGURE_SMP_MAXIMUM_PROCESSORS 2
938    #define CONFIGURE_SCHEDULER_SIMPLE_SMP
939
940    #include <rtems/scheduler.h>
941
942    RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(a);
943    RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(b);
944
945    #define CONFIGURE_SCHEDULER_CONTROLS \
946              RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(a, SCHED_A), \
947              RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(b, SCHED_B)
948    #define CONFIGURE_SMP_SCHEDULER_ASSIGNMENTS \
949              RTEMS_SCHEDULER_ASSIGN(0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY), \
950             RTEMS_SCHEDULER_ASSIGN(1, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY)
951    #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
952    #define CONFIGURE_INIT
953    #include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.