9.10 Shared Variables
Static Semantics
If two different
objects, including nonoverlapping parts of the same object, are
independently
addressable, they can be manipulated concurrently by two different
tasks without synchronization. Any two nonoverlapping objects are independently
addressable if either object is specified as independently addressable
(see
C.6). Otherwise, two nonoverlapping objects
are independently addressable except when they are both parts of a composite
object for which a nonconfirming value is specified for any of the following
representation aspects: (record) Layout, Component_Size, Pack, Atomic,
or Convention; in this case it is unspecified whether the parts are independently
addressable.
Dynamic Semantics
Separate tasks normally
proceed independently and concurrently with one another. However, task
interactions can be used to synchronize the actions of two or more tasks
to allow, for example, meaningful communication by the direct updating
and reading of variables shared between the tasks. The actions of two
different tasks are synchronized in this sense when an action of one
task
signals an action of the other task;
an
action A1 is defined to signal an action A2 under the following circumstances:
If A1 and A2 are part of the execution of the same
task, and the language rules require A1 to be performed before A2;
If A1 is the action of an activator that initiates
the activation of a task, and A2 is part of the execution of the task
that is activated;
If A1 is part of the activation of a task, and
A2 is the action of waiting for completion of the activation;
If A1 is part of the execution of a task, and A2
is the action of waiting for the termination of the task;
If A1 is the termination of a task T, and A2 is
either an evaluation of the expression T'Terminated that results in True,
or a call to Ada.Task_Identification.Is_Terminated with an actual parameter
that identifies T and a result of True (see
C.7.1);
If A1 is the action of issuing an entry call, and
A2 is part of the corresponding execution of the appropriate
entry_body
or
accept_statement;
If A1 is part of the execution of an
accept_statement
or
entry_body,
and A2 is the action of returning from the corresponding entry call;
If A1 is part of the execution of a protected procedure
body or
entry_body
for a given protected object, and A2 is part of a later execution of
an
entry_body
for the same protected object;
If A1 signals some
action that in turn signals A2.
Erroneous Execution
Given
an action of assigning to an object, and an action of reading or updating
a part of the same object (or of a neighboring object if the two are
not independently addressable), then the execution of the actions is
erroneous unless the actions are
sequential.
Two
actions are sequential if one of the following is true:
One action signals the other;
Both actions occur as part of the execution of
the same task;
Both actions occur as part of protected actions
on the same protected object, and at most one of the actions is part
of a call on a protected function of the protected object.
Aspect Atomic or aspect Atomic_Components may also
be specified to ensure that certain reads and updates are sequential
— see
C.6.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe