source: rtems/doc/user/sem.t @ dafa5d88

Last change on this file since dafa5d88 was dafa5d88, checked in by Sebastian Huber <sebastian.huber@…>, on Sep 3, 2015 at 8:27:16 AM

score: Implement priority boosting

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