9.3 Task Dependence - Termination of Tasks
Dynamic Semantics
{dependence
(of a task on a master)} {task
(dependence)} {task
(completion)} {task
(termination)} Each task (other than an
environment task — see
10.2)
depends
on one or more masters (see
7.6.1), as follows:
If the task is created by the evaluation of an
allocator
for a given access type, it depends on each master that includes the
elaboration of the declaration of the ultimate ancestor of the given
access type.
If the task is created by the elaboration of an
object_declaration,
it depends on each master that includes this elaboration.
{
AI95-00416-01}
Otherwise, the task depends on the master of the outermost object of
which it is a part (as determined by the accessibility level of that
object — see
3.10.2 and
7.6.1),
as well as on any master whose execution includes that of the master
of the outermost object.
Ramification: {
AI95-00416-01}
The master of a task created by a return statement changes when the accessibility
of the return object changes. Note that its activation happens, if at
all, only after the function returns and all accessibility level changes
have occurred.
{dependence (of a
task on another task)} Furthermore, if
a task depends on a given master, it is defined to depend on the task
that executes the master, and (recursively) on any master of that task.
A task is said to be
completed when the execution
of its corresponding
task_body
is completed. A task is said to be
terminated when any finalization
of the
task_body
has been performed (see
7.6.1). [The first
step of finalizing a master (including a
task_body)
is to wait for the termination of any tasks dependent on the master.]
{blocked (waiting for dependents to terminate)
[partial]} The task executing the master is
blocked until all the dependents have terminated. [Any remaining finalization
is then performed and the master is left.]
When both conditions are satisfied, the task considered
becomes completed, together with all tasks that depend on the master
considered that are not yet completed.
Ramification: Any required finalization
is performed after the selection of
terminate_alternatives.
The tasks are not callable during the finalization. In some ways it is
as though they were aborted.
8 The full view of a limited private type
can be a task type, or can have subcomponents of a task type. Creation
of an object of such a type creates dependences according to the full
type.
10 The rules given for the collective completion
of a group of tasks all blocked on
select_statements
with open
terminate_alternatives
ensure that the collective completion can occur only when there are no
remaining active tasks that could call one of the tasks being collectively
completed.
12 The completion
of a task can occur due to any of the following:
the abort of the task.
Examples
Example of task
dependence:
declare
type Global
is access Server; --
see 9.1
A, B : Server;
G : Global;
begin
--
activation of A and B
declare
type Local
is access Server;
X : Global :=
new Server; --
activation of X.all
L : Local :=
new Server; --
activation of L.all
C : Server;
begin
--
activation of C
G := X; --
both G and X designate the same task object
...
end; --
await termination of C and L.all (but not X.all)
...
end; --
await termination of A, B, and G.all
Wording Changes from Ada 83
Tasks that used to depend on library packages
in Ada 83, now depend on the (implicit)
task_body
of the environment task (see
10.2). Therefore,
the environment task has to wait for them before performing library level
finalization and terminating the partition. In Ada 83 the requirement
to wait for tasks that depended on library packages was not as clear.
What was "collective termination"
is now "collective completion" resulting from selecting
terminate_alternatives.
This is because finalization still occurs for such tasks, and this happens
after selecting the
terminate_alternative,
but before termination.
Wording Changes from Ada 95
{
AI95-00416-01}
Added missing wording that explained the master of tasks that are neither
object declarations nor allocators, such as function returns.