Section 9: Tasks and Synchronization
{execution (Ada program)
[partial]} The execution of an Ada program
consists of the execution of one or more
tasks.
{task}
{interaction (between
tasks)} Each task represents a separate
thread of control that proceeds independently and concurrently between
the points where it
interacts with other tasks. The various forms
of task interaction are described in this section, and include:
{parallel
processing: See task} {synchronization}
{concurrent processing:
See task} {intertask
communication: See also task}
To be honest: The execution of an Ada
program consists of the execution of one or more partitions (see
10.2),
each of which in turn consists of the execution of an environment task
and zero or more subtasks.
the activation and termination of a task;
{protected object}
a call on a protected subprogram of a
protected
object, providing exclusive read-write access, or concurrent read-only
access to shared data;
a call on an entry, either of another task, allowing
for synchronous communication with that task, or of a protected object,
allowing for asynchronous communication with one or more other tasks
using that same protected object;
a timed operation, including a simple delay statement,
a timed entry call or accept, or a timed asynchronous select statement
(see next item);
an asynchronous transfer of control as part of
an asynchronous select statement, where a task stops what it is doing
and begins execution at a different point in response to the completion
of an entry call or the expiration of a delay;
an abort statement, allowing one task to cause
the termination of another task.
In addition, tasks can communicate indirectly by
reading and updating (unprotected) shared variables, presuming the access
is properly synchronized through some other kind of task interaction.
Static Semantics
{task unit}
The properties of a task are defined by a corresponding
task declaration and
task_body,
which together define a program unit called a
task unit.
Dynamic Semantics
Over time, tasks proceed through various
states.
{task state (inactive) [partial]}
{inactive (a task
state)} {task
state (blocked) [partial]} {blocked
(a task state)} {task
state (ready) [partial]} {ready
(a task state)} {task
state (terminated) [partial]} {terminated
(a task state)} A task is initially
inactive;
upon activation, and prior to its
termination it is either
blocked
(as part of some task interaction) or
ready to run.
{execution
resource (required for a task to run)} While
ready, a task competes for the available
execution resources that
it requires to run.
Discussion: {
task dispatching policy}
{
dispatching policy for tasks}
The
means for selecting which of the ready tasks to run, given the currently
available execution resources, is determined by the
task dispatching
policy in effect, which is generally implementation defined, but
may be controlled by pragmas and operations defined in the Real-Time
Annex (see
D.2 and
D.5).
1 Concurrent task execution may be implemented
on multicomputers, multiprocessors, or with interleaved execution on
a single physical processor. On the other hand, whenever an implementation
can determine that the required semantic effects can be achieved when
parts of the execution of a given task are performed by different physical
processors acting in parallel, it may choose to perform them in this
way.
Wording Changes from Ada 83
The introduction has been rewritten.
We use the term "concurrent" rather
than "parallel" when talking about logically independent execution
of threads of control. The term "parallel" is reserved for
referring to the situation where multiple physical processors run simultaneously.