D.2.1 The Task Dispatching Model
{
AI95-00321-01}
[The task dispatching model specifies task scheduling, based on conceptual
priority-ordered ready queues.]
Static Semantics
{
AI95-00355-01}
The following language-defined library package exists:
{
AI05-0166-1}
Dispatching_Policy_Error :
exception;
end Ada.Dispatching;
Dispatching serves as the parent of other language-defined
library units concerned with task dispatching.
{
AI12-0279-1}
For a noninstance subprogram (including a generic
formal subprogram), a generic subprogram, or an entry, the following
language-defined aspect may be specified with an aspect_specification
(see 13.1.1):
Yield
The type of aspect Yield is Boolean.
Aspect Description
for Yield: Ensures
that a callable entity includes a task dispatching point.
If directly specified,
the aspect_definition
shall be a static expression. If not specified (including by inheritance),
the aspect is False.
{
AI12-0279-1}
{
AI12-0294-1}
If a Yield aspect is specified True for a primitive
subprogram S of a type T, then the aspect is inherited
by the corresponding primitive subprogram of each descendant of T.
Legality Rules
{
AI12-0279-1}
{
AI12-0294-1}
If the Yield aspect is specified for a dispatching
subprogram that inherits the aspect, the specified value shall be confirming.
{
AI12-0279-1}
{
AI12-0294-1}
If the Nonblocking aspect (see 9.5)
of the associated callable entity is statically True, the Yield aspect
shall not be specified as True. For a callable entity that is declared
within a generic body, this rule is checked assuming that any nonstatic
Nonblocking attributes in the expression of the Nonblocking aspect of
the entity are statically True.
Reason: {
AI12-0294-1}
The second sentence here is an assume-the-worst
rule. The only Nonblocking attributes that are nonstatic are those that
depend, directly or indirectly, on the nonblocking aspect of a generic
formal parameter. We have to assume these might in fact have the value
True if given an appropriate actual entity.
{
AI12-0294-1}
In addition to the places where Legality Rules
normally apply (see 12.3), these rules also
apply in the private part of an instance of a generic unit.
Dynamic Semantics
{
AI95-00321-01}
{
AI12-0454-1}
A task can become a
running task only if it is ready (see
Clause
9 9)
and the execution resources required by that task are available. Processors
are allocated to tasks based on each task's active priority.
It is implementation defined whether, on a multiprocessor,
a task that is waiting for access to a protected object keeps its processor
busy.
Implementation defined: Whether, on a
multiprocessor, a task that is waiting for access to a protected object
keeps its processor busy.
{
AI95-00321-01}
{
AI12-0119-1}
Task
dispatching is the process by which
a logical
thread of control associated with a one
ready task is selected for execution on a processor. This selection is
done
at certain points during the execution
of
such a logical thread of control, at certain
points a task called
task dispatching
points.
Such a logical thread of control A
task reaches a task dispatching point whenever it becomes blocked,
and when
its associated task it
terminates. [Other task dispatching points are defined throughout this
Annex for specific policies.]
Below we talk in
terms of tasks, but in the context of a parallel construct, a single
task can be represented by multiple logical threads of control, each
of which can appear separately on a ready queue.
Ramification: On multiprocessor systems,
more than one task can be chosen, at the same time, for execution on
more than one processor, as explained below.
{
AI95-00321-01}
Task
dispatching policies are specified in terms of conceptual
ready
queues and task states. A ready queue is an ordered list of ready
tasks. The first position in a queue is called the
head of the queue,
and the last position is called the
tail of the queue. A task
is
ready if it is in a ready queue, or if it is running. Each
processor has one ready queue for each priority value. At any instant,
each ready queue of a processor contains exactly the set of tasks of
that priority that are ready for execution on that processor, but are
not running on any processor; that is, those tasks that are ready, are
not running on any processor, and can be executed using that processor
and other available resources. A task can be on the ready queues of more
than one processor.
Discussion: The core language defines
a ready task as one that is not blocked. Here we refine this definition
and talk about ready queues.
{
AI95-00321-01}
Each processor also has one
running task,
which is the task currently being executed by that processor. Whenever
a task running on a processor reaches a task dispatching point it goes
back to one or more ready queues; a task (possibly the same task) is
then selected to run on that processor. The task selected is the one
at the head of the highest priority nonempty ready queue; this task is
then removed from all ready queues to which it belongs.
Discussion: There is always at least
one task to run, if we count the idle task.
This paragraph
was deleted.
{
AI95-00321-01}
{
AI12-0279-1}
If the Yield aspect has the value True, then a
call to procedure Yield is included within the body of the associated
callable entity, and invoked immediately prior to returning from the
body if and only if no other task dispatching points were encountered
during the execution of the body.
This paragraph
was deleted.
Implementation Permissions
{
AI95-00321-01}
An implementation is allowed to define additional resources as execution
resources, and to define the corresponding allocation policies for them.
Such resources may have an implementation-defined effect on task dispatching.
Implementation defined: The effect of
implementation-defined execution resources on task dispatching.
An implementation may place implementation-defined
restrictions on tasks whose active priority is in the Interrupt_Priority
range.
Ramification: {
AI05-0229-1}
For example, on some operating systems, it might be necessary to disallow
them altogether. This permission applies to tasks whose priority is set
to interrupt level for any reason: via an aspect, via a call to Dynamic_Priorities.Set_Priority,
or via priority inheritance.
{
AI95-00321-01}
{
AI12-0299-1}
Unless otherwise specified for a task dispatching
policy, [For optimization purposes,]
an implementation may
add additional alter
the points at which task dispatching
may
occur occurs, in an implementation-defined
manner.
However, a delay_statement
always corresponds to at least one task dispatching point.
Reason: {
AI12-0299-1}
This permission is intended to allow the implementation
of Ada tasks in terms of target system threads, which may have additional
conditions that cause task dispatching. For instance, for Linux threads,
page faults are task dispatching points.
Discussion: {
AI12-0299-1}
The Non_Preemptive_FIFO_Within_Priorities task
dispatching policy (see D.2.4) does not allow
additional task dispatching points.
NOTE 1 Clause
9
specifies under which circumstances a task becomes ready. The ready state
is affected by the rules for task activation and termination, delay statements,
and entry calls.
When a task is not ready, it is
said to be blocked.
NOTE 2 {
AI12-0442-1}
An example of a possible implementation-defined execution resource is
a page of physical memory, which
must needs
to be loaded with a particular page of virtual memory before a
task can continue execution.
NOTE 3 The ready queues are purely
conceptual; there is no requirement that such lists physically exist
in an implementation.
NOTE 4 While a task is running, it
is not on any ready queue. Any time the task that is running on a processor
is added to a ready queue, a new running task is selected for that processor.
NOTE 5 In a multiprocessor system,
a task can be on the ready queues of more than one processor. At the
extreme, if several processors share the same set of ready tasks, the
contents of their ready queues is identical, and so they can be viewed
as sharing one ready queue, and can be implemented that way. [Thus, the
dispatching model covers multiprocessors where dispatching is implemented
using a single ready queue, as well as those with separate dispatching
domains.]
NOTE 7 {
AI95-00321-01}
The setting of a task's base priority as a result of a call to Set_Priority
does not always take effect immediately when Set_Priority is called.
The effect of setting the task's base priority is deferred while the
affected task performs a protected action.
Wording Changes from Ada 95
{
AI95-00321-01}
{
AI05-0005-1}
This description is simplified to describe only the parts of the dispatching
model common to all policies. In particular, rules about preemption are
moved elsewhere. This makes it easier to add other policies (which might
not involve preemption).
Incompatibilities With Ada 2005
{
AI05-0166-1}
Procedure Yield is added to Dispatching. If Dispatching
is referenced in a
use_clause,
and an entity
E with a
defining_identifier
of Yield is defined in a package that is also referenced in a
use_clause,
the entity
E may no longer be use-visible, resulting in errors.
This should be rare and is easily fixed if it does occur.
{
AI05-0166-1}
{
AI12-0005-1}
Package Dispatching was a Pure package, but now
is Preelaborated with the addition of Yield. This is incompatible as
Dispatching can no longer be depended upon from a Pure package. This
should happen rarely in practice as the only contents was the exception
Dispatching_Policy_Error and none of the child packages that could raise
that exception are pure.
Inconsistencies With Ada 2012
{
AI12-0299-1}
Correction: Substantially
reduced the Implementation Permission that used to allow “altering”
task dispatching points to only allow adding task dispatching points.
If an implementation was using this permission to remove task dispatching
points, and a program depended on that behavior to work, it could fail
when used with Ada 2022. We are not aware of any such implementations,
and such behavior was never portable to other implementations, so we
do not expect this to matter in practice.
Extensions to Ada 2012
Wording Changes from Ada 2012
{
AI12-0119-1}
Redid the description of task dispatching to include
the separate threads of control that can be started by a parallel construct.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe