D.4 Entry Queuing Policies
1/1
{
8652/0074}
{
AI95-00068-01}
[
{queuing policy} This
clause specifies a mechanism for a user to choose an entry
queuing
policy. It also defines
two one
such polic
ies y.
Other policies are implementation defined.]
1.a
Implementation defined: Implementation-defined
queuing policies.
Syntax
2
The form of
a pragma Queuing_Policy is as follows:
3
pragma Queuing_Policy(
policy_identifier);
Legality Rules
4
The
policy_identifier
shall be either FIFO_Queuing, Priority_Queuing or an implementation-defined
identifier.
Post-Compilation Rules
5
{configuration pragma
(Queuing_Policy) [partial]} {pragma,
configuration (Queuing_Policy) [partial]} A
Queuing_Policy pragma is a configuration pragma.
Dynamic Semantics
6
{queuing policy}
[A
queuing policy governs the order in which
tasks are queued for entry service, and the order in which different
entry queues are considered for service.] The queuing policy is specified
by a Queuing_Policy pragma.
6.a
Ramification: The queuing policy includes
entry queuing order, the choice among open alternatives of a selective_accept,
and the choice among queued entry calls of a protected object when more
than one entry_barrier condition
is True.
7/2
{
AI95-00355-01}
Two queuing policies, FIFO_Queuing and Priority_Queuing, are language
defined. If no Queuing_Policy pragma
applies to appears
in any of the program units comprising the partition, the queuing
policy for that partition is FIFO_Queuing. The rules for this policy
are specified in
9.5.3 and
9.7.1.
8
The Priority_Queuing
policy is defined as follows:
9
- {priority
of an entry call} The calls to an entry
[(including a member of an entry family)] are queued in an order consistent
with the priorities of the calls. The priority of an entry call
is initialized from the active priority of the calling task at the time
the call is made, but can change later. Within the same priority, the
order is consistent with the calling (or requeuing, or priority setting)
time (that is, a FIFO order).
10/1
- {8652/0075}
{AI95-00205-01}
After a call is first queued, changes to the active priority of a task
do not affect the priority of the call, unless the base priority of the
task is set while the task is blocked on an entry
call.
11
- When the base priority of a task is
set (see D.5), if the task is blocked on an
entry call, and the call is queued, the priority of the call is updated
to the new active priority of the calling task. This causes the call
to be removed from and then reinserted in the queue at the new active
priority.
11.a
Reason: A task is blocked on an entry
call if the entry call is simple, conditional, or timed. If the call
came from the triggering_statement of an asynchronous_select,
or a requeue thereof, then the task is not blocked on that call; such
calls do not have their priority updated. Thus, there can exist many
queued calls from a given task (caused by many nested ATC's), but a task
can be blocked on only one call at a time.
11.b
A previous version of Ada 9X required queue
reordering in the asynchronous_select case
as well. If the call corresponds to a “synchronous” entry
call, then the task is blocked while queued, and it makes good sense
to move it up in the queue if its priority is raised.
11.c
However, if the entry call is “asynchronous,”
that is, it is due to an asynchronous_select
whose triggering_statement is an entry call,
then the task is not waiting for this entry call, so the placement of
the entry call on the queue is irrelevant to the rate at which the task
proceeds.
11.d
Furthermore, when an entry is used for asynchronous_selects,
it is almost certain to be a “broadcast” entry or have only
one caller at a time. For example, if the entry is used to notify tasks
of a mode switch, then all tasks on the entry queue would be signaled
when the mode changes. Similarly, if it is indicating some interrupting
event such as a control-C, all tasks sensitive to the interrupt will
want to be informed that the event occurred. Hence, the order on such
a queue is essentially irrelevant.
11.e
Given the above, it seems an unnecessary semantic
and implementation complexity to specify that asynchronous queued calls
are moved in response to dynamic priority changes. Furthermore, it is
somewhat inconsistent, since the call was originally queued based on
the active priority of the task, but dynamic priority changes are changing
the base priority of the task, and only indirectly the active priority.
We say explicitly that asynchronous queued calls are not affected by
normal changes in active priority during the execution of an abortable_part.
Saying that, if a change in the base priority affects the active priority,
then we do want the calls reordered, would be inconsistent. It would
also require the implementation to maintain a readily accessible list
of all queued calls which would not otherwise be necessary.
11.f
Several rules were removed or simplified when
we changed the rules so that calls due to asynchronous_selects
are never moved due to intervening changes in active priority, be they
due to protected actions, some other priority inheritance, or changes
in the base priority.
12
- When more than one condition
of an entry_barrier of a protected object
becomes True, and more than one of the respective queues is nonempty,
the call with the highest priority is selected. If more than one such
call has the same priority, the call that is queued on the entry whose
declaration is first in textual order in the protected_definition
is selected. For members of the same entry family, the one with the lower
family index is selected.
13
- If the expiration time of two or more
open delay_alternatives is the same and no
other accept_alternatives are open, the sequence_of_statements
of the delay_alternative that is first in
textual order in the selective_accept is executed.
14
- When more than one alternative of
a selective_accept is open and has queued
calls, an alternative whose queue has the highest-priority call at its
head is selected. If two or more open alternatives have equal-priority
queued calls, then a call on the entry in the accept_alternative
that is first in textual order in the selective_accept
is selected.
Implementation Permissions
15/2
{
AI95-00256-01}
Implementations are allowed to define other queuing policies, but need
not support more than one
queuing such
policy per partition.
15.a.1/2
Discussion: {
8652/0116}
{
AI95-00069-01}
{
AI95-00256-01}
This rule is really redundant, as 10.1.5
allows an implementation to limit the use of configuration pragmas to
an empty environment. In that case, there would be no way to have multiple
policies in a partition. In any case, the wording here really ought to be "...more than one
queuing policy per partition.", since this part of the rule applies
to all queuing policies, not just implementation-defined ones.
15.1/2
{
AI95-00188-02}
Implementations are allowed to defer the reordering
of entry queues following a change of base priority of a task blocked
on the entry call if it is not practical to reorder the queue immediately.
15.a.2/2
Reason: Priority
change is immediate, but the effect of the change on entry queues can
be deferred. That is necessary in order to implement priority changes
on top of a non-Ada kernel.
15.a.3/2
Discussion: The
reordering should occur as soon as the blocked task can itself perform
the reinsertion into the entry queue.
Implementation Advice
16
The implementation should use names that end with
“_Queuing” for implementation-defined queuing policies.
16.a/2
Implementation Advice:
Names that end with “_Queuing”
should be used for implementation-defined queuing policies.
Wording Changes from Ada 95
16.b/2
16.c/2
{
8652/0075}
{
AI95-00205-01}
Corrigendum: Corrected so that a call of
Set_Priority in an abortable part does not change the priority of the
triggering entry call.
16.d/2
{
AI95-00188-02}
Added a permission to defer queue reordering when
the base priority of a task is changed. This is a counterpart to stronger
requirements on the implementation of priority change.
16.e/2
{
AI95-00256-01}
Clarified that an implementation need support only
one queuing policy (of any kind, language-defined or otherwise) per partition.
16.f/2
{
AI95-00355-01}
Fixed wording to make clear that pragma
never appears inside of a unit; rather it “applies to” the
unit.