10.2 Program Execution
An
Ada
program consists of a set of
partitions, which can
execute in parallel with one another, possibly in a separate address
space, and possibly on a separate computer.
Post-Compilation Rules
A partition
is a program or part of a program that can be invoked from outside the
Ada implementation. For example, on many systems, a partition can be
an executable file generated by the system linker.
The
user can
explicitly assign library units to a partition. The assignment
is done in an implementation-defined manner. The compilation units included
in a partition are those of the explicitly assigned library units, as
well as other compilation units
needed by those library units.
The compilation units needed by a given compilation unit (the
needed
compilation units) are determined as follows (unless specified otherwise
via an implementation-defined
pragma,
or by some other implementation-defined means):
A compilation unit is a needed compilation unit
of itself;
If a compilation unit is among the needed compilation
units, then so are any compilation units upon which it depends semantically;
If a compilation unit with stubs is among the needed
compilation units, then so are any corresponding subunits;
If the (implicit) declaration of the limited view
of a library package is among the needed compilation units, then so is
the explicit declaration of the library package.
The user can optionally designate
(in an implementation-defined manner) one subprogram as the
main subprogram
for the partition. A main subprogram, if specified, shall be a subprogram.
Each partition has an anonymous
environment task, which is an implicit outermost task whose execution
elaborates the
library_items
of the environment
declarative_part,
and then calls the main subprogram, if there is one. A partition's execution
is that of its tasks.
The order of elaboration of library units is determined
primarily by the
elaboration dependences.
There
is an elaboration dependence of a given
library_item
upon another if the given
library_item
or any of its subunits depends semantically on the other
library_item.
In addition, if a given
library_item
or any of its subunits has a
pragma
Elaborate or Elaborate_All that names another library unit, then there
is an elaboration dependence of the given
library_item
upon the body of the other library unit, and, for Elaborate_All only,
upon each
library_item
that is a needed compilation unit of the declaration of the other library
unit.
The environment task
for a partition has the following structure:
task Environment_Task;
task body Environment_Task is
... (1) --
The environment declarative_part
--
(that is, the sequence of library_items) goes here.
begin
... (2) --
Call the main subprogram, if there is one.
end Environment_Task;
The order of all included
library_items
is such that there are no forward elaboration dependences.
All
library_items
declared pure occur before any that are not declared pure.
All preelaborated
library_items
occur before any that are not preelaborated.
There shall be a total order of the
library_items
that obeys the above rules. The order is otherwise implementation defined.
The full expanded names of the library units and
subunits included in a given partition shall be distinct.
A call to the main subprogram, if the partition
has one. If the main subprogram has parameters, they are passed; where
the actuals come from is implementation defined. What happens to the
result of a main function is also implementation defined.
or:
The mechanisms for building and running partitions
are implementation defined. These can be combined into one operation,
as, for example, in dynamic linking, or “load-and-go” systems.
Dynamic Semantics
The execution of a program consists
of the execution of a set of partitions. Further details are implementation
defined.
The execution of a partition starts with
the execution of its environment task, ends when the environment task
terminates, and includes the executions of all tasks of the partition.
The execution of the (implicit)
task_body
of the environment task acts as a master for all other tasks created
as part of the execution of the partition. When the environment task
completes (normally or abnormally), it waits for the termination of all
such tasks, and then finalizes any remaining objects of the partition.
Bounded (Run-Time) Errors
Once the
environment task has awaited the termination of all other tasks of the
partition, any further attempt to create a task (during finalization)
is a bounded error, and may result in the raising of Program_Error either
upon creation or activation of the task.
If such
a task is activated, it is not specified whether the task is awaited
prior to termination of the environment task.
Implementation Requirements
The implementation
shall ensure that all compilation units included in a partition are consistent
with one another, and are legal according to the rules of the language.
Implementation Permissions
The kind of partition described
in this subclause is known as an
active partition. An implementation
is allowed to support other kinds of partitions, with implementation-defined
semantics.
An implementation may restrict the kinds of subprograms
it supports as main subprograms. However, an implementation is required
to support all main subprograms that are public parameterless library
procedures.
If the environment task completes abnormally, the
implementation may abort any dependent tasks.
NOTE 1 An implementation can provide
inter-partition communication mechanism(s) via special packages and pragmas.
Standard pragmas for distribution and methods for specifying inter-partition
communication are defined in
Annex E, “
Distributed
Systems”. If no such mechanisms are provided, then each partition
is isolated from all others, and behaves as a program in and of itself.
NOTE 2 Partitions are not required
to run in separate address spaces. For example, an implementation can
support dynamic linking via the partition concept.
NOTE 3 An order of elaboration of
library_items
that is consistent with the partial ordering defined above does not always
ensure that each
library_unit_body
is elaborated before any other compilation unit whose elaboration necessitates
that the
library_unit_body
be already elaborated. (In particular, there is no requirement that the
body of a library unit be elaborated as soon as possible after the
library_unit_declaration
is elaborated, unless the pragmas or aspects in
10.2.1
are used.)
NOTE 4 A partition (active or otherwise)
does not necessarily have a main subprogram. In such a case, all the
work done by the partition would be done by elaboration of various
library_items,
and by tasks created by that elaboration. Passive partitions, which cannot
have main subprograms, are defined in
Annex E,
“
Distributed Systems”.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe