summaryrefslogtreecommitdiffstats
path: root/doc/user/sem.t
diff options
context:
space:
mode:
Diffstat (limited to 'doc/user/sem.t')
-rw-r--r--doc/user/sem.t832
1 files changed, 832 insertions, 0 deletions
diff --git a/doc/user/sem.t b/doc/user/sem.t
new file mode 100644
index 0000000000..dd51266892
--- /dev/null
+++ b/doc/user/sem.t
@@ -0,0 +1,832 @@
+@c
+@c COPYRIGHT (c) 1988-2002.
+@c On-Line Applications Research Corporation (OAR).
+@c All rights reserved.
+@c
+@c $Id$
+@c
+
+@chapter Semaphore Manager
+
+@cindex semaphores
+@cindex binary semaphores
+@cindex counting semaphores
+@cindex mutual exclusion
+
+@section Introduction
+
+The semaphore manager utilizes standard Dijkstra
+counting semaphores to provide synchronization and mutual
+exclusion capabilities. The directives provided by the
+semaphore manager are:
+
+@itemize @bullet
+@item @code{@value{DIRPREFIX}semaphore_create} - Create a semaphore
+@item @code{@value{DIRPREFIX}semaphore_ident} - Get ID of a semaphore
+@item @code{@value{DIRPREFIX}semaphore_delete} - Delete a semaphore
+@item @code{@value{DIRPREFIX}semaphore_obtain} - Acquire a semaphore
+@item @code{@value{DIRPREFIX}semaphore_release} - Release a semaphore
+@item @code{@value{DIRPREFIX}semaphore_flush} - Unblock all tasks waiting on a semaphore
+@end itemize
+
+@section Background
+
+A semaphore can be viewed as a protected variable
+whose value can be modified only with the
+@code{@value{DIRPREFIX}semaphore_create},
+@code{@value{DIRPREFIX}semaphore_obtain}, and
+@code{@value{DIRPREFIX}semaphore_release} directives. RTEMS
+supports both binary and counting semaphores. A binary semaphore
+is restricted to values of zero or one, while a counting
+semaphore can assume any non-negative integer value.
+
+A binary semaphore can be used to control access to a
+single resource. In particular, it can be used to enforce
+mutual exclusion for a critical section in user code. In this
+instance, the semaphore would be created with an initial count
+of one to indicate that no task is executing the critical
+section of code. Upon entry to the critical section, a task
+must issue the @code{@value{DIRPREFIX}semaphore_obtain}
+directive to prevent other tasks from entering the critical section.
+Upon exit from the critical section, the task must issue the
+@code{@value{DIRPREFIX}semaphore_release} directive to
+allow another task to execute the critical section.
+
+A counting semaphore can be used to control access to
+a pool of two or more resources. For example, access to three
+printers could be administered by a semaphore created with an
+initial count of three. When a task requires access to one of
+the printers, it issues the @code{@value{DIRPREFIX}semaphore_obtain}
+directive to obtain access to a printer. If a printer is not currently
+available, the task can wait for a printer to become available or return
+immediately. When the task has completed printing, it should
+issue the @code{@value{DIRPREFIX}semaphore_release}
+directive to allow other tasks access to the printer.
+
+Task synchronization may be achieved by creating a
+semaphore with an initial count of zero. One task waits for the
+arrival of another task by issuing a @code{@value{DIRPREFIX}semaphore_obtain}
+directive when it reaches a synchronization point. The other task
+performs a corresponding @code{@value{DIRPREFIX}semaphore_release}
+operation when it reaches its synchronization point, thus unblocking
+the pending task.
+
+@subsection Nested Resource Access
+
+Deadlock occurs when a task owning a binary semaphore
+attempts to acquire that same semaphore and blocks as result.
+Since the semaphore is allocated to a task, it cannot be
+deleted. Therefore, the task that currently holds the semaphore
+and is also blocked waiting for that semaphore will never
+execute again.
+
+RTEMS addresses this problem by allowing the task
+holding the binary semaphore to obtain the same binary semaphore
+multiple times in a nested manner. Each
+@code{@value{DIRPREFIX}semaphore_obtain} must be accompanied with a
+@code{@value{DIRPREFIX}semaphore_release}. The semaphore will
+only be made available for acquisition by other tasks when the
+outermost @code{@value{DIRPREFIX}semaphore_obtain} is matched with
+a @code{@value{DIRPREFIX}semaphore_release}.
+
+Simple binary semaphores do not allow nested access and so can be used for task synchronization.
+
+
+@subsection Priority Inversion
+
+Priority inversion is a form of indefinite
+postponement which is common in multitasking, preemptive
+executives with shared resources. Priority inversion occurs
+when a high priority tasks requests access to shared resource
+which is currently allocated to low priority task. The high
+priority task must block until the low priority task releases
+the resource. This problem is exacerbated when the low priority
+task is prevented from executing by one or more medium priority
+tasks. Because the low priority task is not executing, it
+cannot complete its interaction with the resource and release
+that resource. The high priority task is effectively prevented
+from executing by lower priority tasks.
+
+@subsection Priority Inheritance
+
+Priority inheritance is an algorithm that calls for
+the lower priority task holding a resource to have its priority
+increased to that of the highest priority task blocked waiting
+for that resource. Each time a task blocks attempting to obtain
+the resource, the task holding the resource may have its
+priority increased.
+
+RTEMS supports priority inheritance for local, binary
+semaphores that use the priority task wait queue blocking
+discipline. When a task of higher priority than the task
+holding the semaphore blocks, the priority of the task holding
+the semaphore is increased to that of the blocking task. When
+the task holding the task completely releases the binary
+semaphore (i.e. not for a nested release), the holder's priority
+is restored to the value it had before any higher priority was
+inherited.
+
+The RTEMS implementation of the priority inheritance
+algorithm takes into account the scenario in which a task holds
+more than one binary semaphore. The holding task will execute
+at the priority of the higher of the highest ceiling priority or
+at the priority of the highest priority task blocked waiting for
+any of the semaphores the task holds. Only when the task
+releases ALL of the binary semaphores it holds will its priority
+be restored to the normal value.
+
+@subsection Priority Ceiling
+
+Priority ceiling is an algorithm that calls for the
+lower priority task holding a resource to have its priority
+increased to that of the highest priority task which will EVER
+block waiting for that resource. This algorithm addresses the
+problem of priority inversion although it avoids the possibility
+of changing the priority of the task holding the resource
+multiple times. The priority ceiling algorithm will only change
+the priority of the task holding the resource a maximum of one
+time. The ceiling priority is set at creation time and must be
+the priority of the highest priority task which will ever
+attempt to acquire that semaphore.
+
+RTEMS supports priority ceiling for local, binary
+semaphores that use the priority task wait queue blocking
+discipline. When a task of lower priority than the ceiling
+priority successfully obtains the semaphore, its priority is
+raised to the ceiling priority. When the task holding the task
+completely releases the binary semaphore (i.e. not for a nested
+release), the holder's priority is restored to the value it had
+before any higher priority was put into effect.
+
+The need to identify the highest priority task which
+will attempt to obtain a particular semaphore can be a difficult
+task in a large, complicated system. Although the priority
+ceiling algorithm is more efficient than the priority
+inheritance algorithm with respect to the maximum number of task
+priority changes which may occur while a task holds a particular
+semaphore, the priority inheritance algorithm is more forgiving
+in that it does not require this apriori information.
+
+The RTEMS implementation of the priority ceiling
+algorithm takes into account the scenario in which a task holds
+more than one binary semaphore. The holding task will execute
+at the priority of the higher of the highest ceiling priority or
+at the priority of the highest priority task blocked waiting for
+any of the semaphores the task holds. Only when the task
+releases ALL of the binary semaphores it holds will its priority
+be restored to the normal value.
+
+@subsection Building a Semaphore Attribute Set
+
+In general, an attribute set is built by a bitwise OR
+of the desired attribute components. The following table lists
+the set of valid semaphore attributes:
+
+@itemize @bullet
+@item @code{@value{RPREFIX}FIFO} - tasks wait by FIFO (default)
+
+@item @code{@value{RPREFIX}PRIORITY} - tasks wait by priority
+
+@item @code{@value{RPREFIX}BINARY_SEMAPHORE} - restrict values to
+0 and 1
+
+@item @code{@value{RPREFIX}COUNTING_SEMAPHORE} - no restriction on values
+(default)
+
+@item @code{@value{RPREFIX}SIMPLE_BINARY_SEMAPHORE} - restrict values to
+0 and 1, do not allow nested access, allow deletion of locked semaphore.
+
+@item @code{@value{RPREFIX}NO_INHERIT_PRIORITY} - do not use priority
+inheritance (default)
+
+@item @code{@value{RPREFIX}INHERIT_PRIORITY} - use priority inheritance
+
+@item @code{@value{RPREFIX}PRIORITY_CEILING} - use priority ceiling
+
+@item @code{@value{RPREFIX}NO_PRIORITY_CEILING} - do not use priority
+ceiling (default)
+
+@item @code{@value{RPREFIX}LOCAL} - local task (default)
+
+@item @code{@value{RPREFIX}GLOBAL} - global task
+@end itemize
+
+Attribute values are specifically designed to be
+mutually exclusive, therefore bitwise OR and addition operations
+are equivalent as long as each attribute appears exactly once in
+the component list. An attribute listed as a default is not
+required to appear in the attribute list, although it is a good
+programming practice to specify default attributes. If all
+defaults are desired, the attribute
+@code{@value{RPREFIX}DEFAULT_ATTRIBUTES} should be
+specified on this call.
+
+This example demonstrates the attribute_set parameter needed to create a
+local semaphore with the task priority waiting queue discipline. The
+attribute_set parameter passed to the
+@code{@value{DIRPREFIX}semaphore_create} directive could be either
+@code{@value{RPREFIX}PRIORITY} or @code{@value{RPREFIX}LOCAL @value{OR}
+@value{RPREFIX}PRIORITY}. The attribute_set parameter can be set to
+@code{@value{RPREFIX}PRIORITY} because @code{@value{RPREFIX}LOCAL} is the
+default for all created tasks. If a similar semaphore were to be known
+globally, then the attribute_set parameter would be
+@code{@value{RPREFIX}GLOBAL @value{OR} @value{RPREFIX}PRIORITY}.
+
+@subsection Building a SEMAPHORE_OBTAIN Option Set
+
+In general, an option is built by a bitwise OR of the
+desired option components. The set of valid options for the
+@code{@value{DIRPREFIX}semaphore_obtain} directive are listed
+in the following table:
+
+@itemize @bullet
+@item @code{@value{RPREFIX}WAIT} - task will wait for semaphore (default)
+@item @code{@value{RPREFIX}NO_WAIT} - task should not wait
+@end itemize
+
+Option values are specifically designed to be mutually exclusive,
+therefore bitwise OR and addition operations are equivalent as long as
+each attribute appears exactly once in the component list. An option
+listed as a default is not required to appear in the list, although it is
+a good programming practice to specify default options. If all defaults
+are desired, the option @code{@value{RPREFIX}DEFAULT_OPTIONS} should be
+specified on this call.
+
+This example demonstrates the option parameter needed
+to poll for a semaphore. The option parameter passed to the
+@code{@value{DIRPREFIX}semaphore_obtain}
+directive should be @code{@value{RPREFIX}NO_WAIT}.
+
+@section Operations
+
+@subsection Creating a Semaphore
+
+The @code{@value{DIRPREFIX}semaphore_create} directive creates a binary or
+counting semaphore with a user-specified name as well as an
+initial count. If a binary semaphore is created with a count of
+zero (0) to indicate that it has been allocated, then the task
+creating the semaphore is considered the current holder of the
+semaphore. At create time the method for ordering waiting tasks
+in the semaphore's task wait queue (by FIFO or task priority) is
+specified. Additionally, the priority inheritance or priority
+ceiling algorithm may be selected for local, binary semaphores
+that use the priority task wait queue blocking discipline. If
+the priority ceiling algorithm is selected, then the highest
+priority of any task which will attempt to obtain this semaphore
+must be specified. RTEMS allocates a Semaphore Control Block
+(SMCB) from the SMCB free list. This data structure is used by
+RTEMS to manage the newly created semaphore. Also, a unique
+semaphore ID is generated and returned to the calling task.
+
+@subsection Obtaining Semaphore IDs
+
+When a semaphore is created, RTEMS generates a unique
+semaphore ID and assigns it to the created semaphore until it is
+deleted. The semaphore ID may be obtained by either of two
+methods. First, as the result of an invocation of the
+@code{@value{DIRPREFIX}semaphore_create} directive, the
+semaphore ID is stored in a user provided location. Second,
+the semaphore ID may be obtained later using the
+@code{@value{DIRPREFIX}semaphore_ident} directive. The semaphore ID is
+used by other semaphore manager directives to access this
+semaphore.
+
+@subsection Acquiring a Semaphore
+
+The @code{@value{DIRPREFIX}semaphore_obtain} directive is used to acquire the
+specified semaphore. A simplified version of the
+@code{@value{DIRPREFIX}semaphore_obtain} directive can be described as follows:
+
+@example
+if semaphore's count is greater than zero
+ then decrement semaphore's count
+ else wait for release of semaphore
+
+return SUCCESSFUL
+@end example
+
+When the semaphore cannot be immediately acquired,
+one of the following situations applies:
+
+@itemize @bullet
+@item By default, the calling task will wait forever to
+acquire the semaphore.
+
+@item Specifying @code{@value{RPREFIX}NO_WAIT} forces an immediate return
+with an error status code.
+
+@item Specifying a timeout limits the interval the task will
+wait before returning with an error status code.
+@end itemize
+
+If the task waits to acquire the semaphore, then it
+is placed in the semaphore's task wait queue in either FIFO or
+task priority order. If the task blocked waiting for a binary
+semaphore using priority inheritance and the task's priority is
+greater than that of the task currently holding the semaphore,
+then the holding task will inherit the priority of the blocking
+task. All tasks waiting on a semaphore are returned an error
+code when the semaphore is deleted.
+
+When a task successfully obtains a semaphore using
+priority ceiling and the priority ceiling for this semaphore is
+greater than that of the holder, then the holder's priority will
+be elevated.
+
+@subsection Releasing a Semaphore
+
+The @code{@value{DIRPREFIX}semaphore_release} directive is used to release
+the specified semaphore. A simplified version of the
+@code{@value{DIRPREFIX}semaphore_release} directive can be described as
+follows:
+
+@example
+if no tasks are waiting on this semaphore
+ then increment semaphore's count
+ else assign semaphore to a waiting task
+
+return SUCCESSFUL
+@end example
+
+If this is the outermost release of a binary
+semaphore that uses priority inheritance or priority ceiling and
+the task does not currently hold any other binary semaphores,
+then the task performing the @code{@value{DIRPREFIX}semaphore_release}
+will have its priority restored to its normal value.
+
+@subsection Deleting a Semaphore
+
+The @code{@value{DIRPREFIX}semaphore_delete} directive removes a semaphore
+from the system and frees its control block. A semaphore can be
+deleted by any local task that knows the semaphore's ID. As a
+result of this directive, all tasks blocked waiting to acquire
+the semaphore will be readied and returned a status code which
+indicates that the semaphore was deleted. Any subsequent
+references to the semaphore's name and ID are invalid.
+
+@section Directives
+
+This section details the semaphore manager's
+directives. A subsection is dedicated to each of this manager's
+directives and describes the calling sequence, related
+constants, usage, and status codes.
+
+@c
+@c
+@c
+@page
+@subsection SEMAPHORE_CREATE - Create a semaphore
+
+@cindex create a semaphore
+
+@subheading CALLING SEQUENCE:
+
+@ifset is-C
+@findex rtems_semaphore_create
+@example
+rtems_status_code rtems_semaphore_create(
+ rtems_name name,
+ rtems_unsigned32 count,
+ rtems_attribute attribute_set,
+ rtems_task_priority priority_ceiling,
+ rtems_id *id
+);
+@end example
+@end ifset
+
+@ifset is-Ada
+@example
+procedure Semaphore_Create (
+ Name : in RTEMS.Name;
+ Count : in RTEMS.Unsigned32;
+ Attribute_Set : in RTEMS.Attribute;
+ ID : out RTEMS.ID;
+ Result : out RTEMS.Status_Codes
+);
+@end example
+@end ifset
+
+@subheading DIRECTIVE STATUS CODES:
+@code{@value{RPREFIX}SUCCESSFUL} - semaphore created successfully@*
+@code{@value{RPREFIX}INVALID_NAME} - invalid task name@*
+@code{@value{RPREFIX}INVALID_ADDRESS} - @code{id} is NULL@*
+@code{@value{RPREFIX}TOO_MANY} - too many semaphores created@*
+@code{@value{RPREFIX}NOT_DEFINED} - invalid attribute set@*
+@code{@value{RPREFIX}INVALID_NUMBER} - invalid starting count for binary semaphore@*
+@code{@value{RPREFIX}MP_NOT_CONFIGURED} - multiprocessing not configured@*
+@code{@value{RPREFIX}TOO_MANY} - too many global objects
+
+@subheading DESCRIPTION:
+
+This directive creates a semaphore which resides on
+the local node. The created semaphore has the user-defined name
+specified in name and the initial count specified in count. For
+control and maintenance of the semaphore, RTEMS allocates and
+initializes a SMCB. The RTEMS-assigned semaphore id is returned
+in id. This semaphore id is used with other semaphore related
+directives to access the semaphore.
+
+Specifying PRIORITY in attribute_set causes tasks
+waiting for a semaphore to be serviced according to task
+priority. When FIFO is selected, tasks are serviced in First
+In-First Out order.
+
+@subheading NOTES:
+
+This directive will not cause the calling task to be
+preempted.
+
+The priority inheritance and priority ceiling
+algorithms are only supported for local, binary semaphores that
+use the priority task wait queue blocking discipline.
+
+The following semaphore attribute constants are
+defined by RTEMS:
+
+@itemize @bullet
+@item @code{@value{RPREFIX}FIFO} - tasks wait by FIFO (default)
+
+@item @code{@value{RPREFIX}PRIORITY} - tasks wait by priority
+
+@item @code{@value{RPREFIX}BINARY_SEMAPHORE} - restrict values to
+0 and 1
+
+@item @code{@value{RPREFIX}COUNTING_SEMAPHORE} - no restriction on values
+(default)
+
+@item @code{@value{RPREFIX}SIMPLE_BINARY_SEMAPHORE} - restrict values to
+0 and 1, block on nested access, allow deletion of locked semaphore.
+
+@item @code{@value{RPREFIX}NO_INHERIT_PRIORITY} - do not use priority
+inheritance (default)
+
+@item @code{@value{RPREFIX}INHERIT_PRIORITY} - use priority inheritance
+
+@item @code{@value{RPREFIX}PRIORITY_CEILING} - use priority ceiling
+
+@item @code{@value{RPREFIX}NO_PRIORITY_CEILING} - do not use priority
+ceiling (default)
+
+@item @code{@value{RPREFIX}LOCAL} - local task (default)
+
+@item @code{@value{RPREFIX}GLOBAL} - global task
+@end itemize
+
+Semaphores should not be made global unless remote
+tasks must interact with the created semaphore. This is to
+avoid the system overhead incurred by the creation of a global
+semaphore. When a global semaphore is created, the semaphore's
+name and id must be transmitted to every node in the system for
+insertion in the local copy of the global object table.
+
+The total number of global objects, including
+semaphores, is limited by the maximum_global_objects field in
+the Configuration Table.
+
+@c
+@c
+@c
+@page
+@subsection SEMAPHORE_IDENT - Get ID of a semaphore
+
+@cindex get ID of a semaphore
+@cindex obtain ID of a semaphore
+
+@subheading CALLING SEQUENCE:
+
+@ifset is-C
+@findex rtems_semaphore_ident
+@example
+rtems_status_code rtems_semaphore_ident(
+ rtems_name name,
+ rtems_unsigned32 node,
+ rtems_id *id
+);
+@end example
+@end ifset
+
+@ifset is-Ada
+@example
+procedure Semaphore_Ident (
+ Name : in RTEMS.Name;
+ Node : in RTEMS.Unsigned32;
+ ID : out RTEMS.ID;
+ Result : out RTEMS.Status_Codes
+);
+@end example
+@end ifset
+
+@subheading DIRECTIVE STATUS CODES:
+@code{@value{RPREFIX}SUCCESSFUL} - semaphore identified successfully@*
+@code{@value{RPREFIX}INVALID_NAME} - semaphore name not found@*
+@code{@value{RPREFIX}INVALID_NODE} - invalid node id
+
+@subheading DESCRIPTION:
+
+This directive obtains the semaphore id associated
+with the semaphore name. If the semaphore name is not unique,
+then the semaphore id will match one of the semaphores with that
+name. However, this semaphore id is not guaranteed to
+correspond to the desired semaphore. The semaphore id is used
+by other semaphore related directives to access the semaphore.
+
+@subheading NOTES:
+
+This directive will not cause the running task to be
+preempted.
+
+If node is @code{@value{RPREFIX}SEARCH_ALL_NODES}, all nodes are searched
+with the local node being searched first. All other nodes are
+searched with the lowest numbered node searched first.
+
+If node is a valid node number which does not
+represent the local node, then only the semaphores exported by
+the designated node are searched.
+
+This directive does not generate activity on remote
+nodes. It accesses only the local copy of the global object
+table.
+
+@c
+@c
+@c
+@page
+@subsection SEMAPHORE_DELETE - Delete a semaphore
+
+@cindex delete a semaphore
+
+@subheading CALLING SEQUENCE:
+
+@ifset is-C
+@findex rtems_semaphore_delete
+@example
+rtems_status_code rtems_semaphore_delete(
+ rtems_id id
+);
+@end example
+@end ifset
+
+@ifset is-Ada
+@example
+procedure Semaphore_Delete (
+ ID : in RTEMS.ID;
+ Result : out RTEMS.Status_Codes
+);
+@end example
+@end ifset
+
+@subheading DIRECTIVE STATUS CODES:
+@code{@value{RPREFIX}SUCCESSFUL} - semaphore deleted successfully@*
+@code{@value{RPREFIX}INVALID_ID} - invalid semaphore id@*
+@code{@value{RPREFIX}ILLEGAL_ON_REMOTE_OBJECT} - cannot delete remote semaphore@*
+@code{@value{RPREFIX}RESOURCE_IN_USE} - binary semaphore is in use
+
+@subheading DESCRIPTION:
+
+This directive deletes the semaphore specified by @code{id}.
+All tasks blocked waiting to acquire the semaphore will be
+readied and returned a status code which indicates that the
+semaphore was deleted. The SMCB for this semaphore is reclaimed
+by RTEMS.
+
+@subheading NOTES:
+
+The calling task will be preempted if it is enabled
+by the task's execution mode and a higher priority local task is
+waiting on the deleted semaphore. The calling task will NOT be
+preempted if all of the tasks that are waiting on the semaphore
+are remote tasks.
+
+The calling task does not have to be the task that
+created the semaphore. Any local task that knows the semaphore
+id can delete the semaphore.
+
+When a global semaphore is deleted, the semaphore id
+must be transmitted to every node in the system for deletion
+from the local copy of the global object table.
+
+The semaphore must reside on the local node, even if
+the semaphore was created with the @code{@value{RPREFIX}GLOBAL} option.
+
+Proxies, used to represent remote tasks, are
+reclaimed when the semaphore is deleted.
+
+@c
+@c
+@c
+@page
+@subsection SEMAPHORE_OBTAIN - Acquire a semaphore
+
+@cindex obtain a semaphore
+@cindex lock a semaphore
+
+@subheading CALLING SEQUENCE:
+
+@ifset is-C
+@findex rtems_semaphore_obtain
+@example
+rtems_status_code rtems_semaphore_obtain(
+ rtems_id id,
+ rtems_unsigned32 option_set,
+ rtems_interval timeout
+);
+@end example
+@end ifset
+
+@ifset is-Ada
+@example
+procedure Semaphore_Obtain (
+ ID : in RTEMS.ID;
+ Option_Set : in RTEMS.Option;
+ Timeout : in RTEMS.Interval;
+ Result : out RTEMS.Status_Codes
+);
+@end example
+@end ifset
+
+@subheading DIRECTIVE STATUS CODES:
+@code{@value{RPREFIX}SUCCESSFUL} - semaphore obtained successfully@*
+@code{@value{RPREFIX}UNSATISFIED} - semaphore not available@*
+@code{@value{RPREFIX}TIMEOUT} - timed out waiting for semaphore@*
+@code{@value{RPREFIX}OBJECT_WAS_DELETED} - semaphore deleted while waiting@*
+@code{@value{RPREFIX}INVALID_ID} - invalid semaphore id
+
+@subheading DESCRIPTION:
+
+This directive acquires the semaphore specified by
+id. The @code{@value{RPREFIX}WAIT} and @code{@value{RPREFIX}NO_WAIT} components of the options parameter
+indicate whether the calling task wants to wait for the
+semaphore to become available or return immediately if the
+semaphore is not currently available. With either @code{@value{RPREFIX}WAIT} or
+@code{@value{RPREFIX}NO_WAIT}, if the current semaphore count is positive, then it is
+decremented by one and the semaphore is successfully acquired by
+returning immediately with a successful return code.
+
+If the calling task chooses to return immediately and the current
+semaphore count is zero or negative, then a status code is returned
+indicating that the semaphore is not available. If the calling task
+chooses to wait for a semaphore and the current semaphore count is zero or
+negative, then it is decremented by one and the calling task is placed on
+the semaphore's wait queue and blocked. If the semaphore was created with
+the @code{@value{RPREFIX}PRIORITY} attribute, then the calling task is
+inserted into the queue according to its priority. However, if the
+semaphore was created with the @code{@value{RPREFIX}FIFO} attribute, then
+the calling task is placed at the rear of the wait queue. If the binary
+semaphore was created with the @code{@value{RPREFIX}INHERIT_PRIORITY}
+attribute, then the priority of the task currently holding the binary
+semaphore is guaranteed to be greater than or equal to that of the
+blocking task. If the binary semaphore was created with the
+@code{@value{RPREFIX}PRIORITY_CEILING} attribute, a task successfully
+obtains the semaphore, and the priority of that task is greater than the
+ceiling priority for this semaphore, then the priority of the task
+obtaining the semaphore is elevated to that of the ceiling.
+
+The timeout parameter specifies the maximum interval the calling task is
+willing to be blocked waiting for the semaphore. If it is set to
+@code{@value{RPREFIX}NO_TIMEOUT}, then the calling task will wait forever.
+If the semaphore is available or the @code{@value{RPREFIX}NO_WAIT} option
+component is set, then timeout is ignored.
+
+@subheading NOTES:
+The following semaphore acquisition option constants
+are defined by RTEMS:
+
+@itemize @bullet
+@item @code{@value{RPREFIX}WAIT} - task will wait for semaphore (default)
+@item @code{@value{RPREFIX}NO_WAIT} - task should not wait
+@end itemize
+
+Attempting to obtain a global semaphore which does not reside on the local
+node will generate a request to the remote node to access the semaphore.
+If the semaphore is not available and @code{@value{RPREFIX}NO_WAIT} was
+not specified, then the task must be blocked until the semaphore is
+released. A proxy is allocated on the remote node to represent the task
+until the semaphore is released.
+
+A clock tick is required to support the timeout functionality of
+this directive.
+
+@c
+@c
+@c
+@page
+@subsection SEMAPHORE_RELEASE - Release a semaphore
+
+@cindex release a semaphore
+@cindex unlock a semaphore
+
+@subheading CALLING SEQUENCE:
+
+@ifset is-C
+@findex rtems_semaphore_release
+@example
+rtems_status_code rtems_semaphore_release(
+ rtems_id id
+);
+@end example
+@end ifset
+
+@ifset is-Ada
+@example
+procedure Semaphore_Release (
+ ID : in RTEMS.ID;
+ Result : out RTEMS.Status_Codes
+);
+@end example
+@end ifset
+
+@subheading DIRECTIVE STATUS CODES:
+@code{@value{RPREFIX}SUCCESSFUL} - semaphore released successfully@*
+@code{@value{RPREFIX}INVALID_ID} - invalid semaphore id@*
+@code{@value{RPREFIX}NOT_OWNER_OF_RESOURCE} - calling task does not own semaphore
+
+@subheading DESCRIPTION:
+
+This directive releases the semaphore specified by
+id. The semaphore count is incremented by one. If the count is
+zero or negative, then the first task on this semaphore's wait
+queue is removed and unblocked. The unblocked task may preempt
+the running task if the running task's preemption mode is
+enabled and the unblocked task has a higher priority than the
+running task.
+
+@subheading NOTES:
+
+The calling task may be preempted if it causes a
+higher priority task to be made ready for execution.
+
+Releasing a global semaphore which does not reside on
+the local node will generate a request telling the remote node
+to release the semaphore.
+
+If the task to be unblocked resides on a different
+node from the semaphore, then the semaphore allocation is
+forwarded to the appropriate node, the waiting task is
+unblocked, and the proxy used to represent the task is reclaimed.
+
+The outermost release of a local, binary, priority
+inheritance or priority ceiling semaphore may result in the
+calling task having its priority lowered. This will occur if
+the calling task holds no other binary semaphores and it has
+inherited a higher priority.
+
+@c
+@c
+@c
+@page
+@subsection SEMAPHORE_FLUSH - Unblock all tasks waiting on a semaphore
+
+@cindex flush a semaphore
+@cindex unblock all tasks waiting on a semaphore
+
+@subheading CALLING SEQUENCE:
+
+@ifset is-C
+@findex rtems_semaphore_flush
+@example
+rtems_status_code rtems_semaphore_flush(
+ rtems_id id
+);
+@end example
+@end ifset
+
+@ifset is-Ada
+@example
+procedure Semaphore_Flush (
+ ID : in RTEMS.ID;
+ Result : out RTEMS.Status_Codes
+);
+@end example
+@end ifset
+
+@subheading DIRECTIVE STATUS CODES:
+@code{@value{RPREFIX}SUCCESSFUL} - semaphore released successfully@*
+@code{@value{RPREFIX}INVALID_ID} - invalid semaphore id@*
+@code{@value{RPREFIX}ILLEGAL_ON_REMOTE_OBJECT} - not supported for remote semaphores
+
+@subheading DESCRIPTION:
+
+This directive unblocks all tasks waiting on the semaphore specified by
+id. Since there are tasks blocked on the semaphore, the semaphore's
+count is not changed by this directive and thus is zero before and
+after this directive is executed. Tasks which are unblocked as the
+result of this directive will return from the
+@code{@value{DIRPREFIX}semaphore_release} directive with a
+status code of @code{@value{RPREFIX}UNSATISFIED} to indicate
+that the semaphore was not obtained.
+
+This directive may unblock any number of tasks. Any of the unblocked
+tasks may preempt the running task if the running task's preemption mode is
+enabled and an unblocked task has a higher priority than the
+running task.
+
+@subheading NOTES:
+
+The calling task may be preempted if it causes a
+higher priority task to be made ready for execution.
+
+If the task to be unblocked resides on a different
+node from the semaphore, then the waiting task is
+unblocked, and the proxy used to represent the task is reclaimed.
+
+