C.6 Shared Variable Control
1/3
{
AI05-0229-1}
[This clause
defines specifies
representation
aspects pragmas
that control the use of shared variables.]
Syntax
2/3
{
AI05-0229-1}
The form for pragmas Atomic, Volatile, Atomic_Components,
and Volatile_Components is as follows:
3/3
4/3
5/3
6/3
Static Semantics
6.1/3
6.2/3
Atomic
The type of aspect Atomic is Boolean.
6.a/3
Aspect Description
for Atomic: Declare
that a type, object, or component is atomic.
6.3/3
Independent
The type of aspect Independent is Boolean.
6.b/3
Aspect Description
for Independent: Declare
that a type, object, or component is independently addressable.
6.4/3
Volatile
The type of aspect Volatile is Boolean.
6.c/3
Aspect Description
for Volatile: Declare
that a type, object, or component is volatile.
6.5/3
6.6/3
Atomic_Components
The type of aspect Atomic_Components is Boolean.
6.d/3
Aspect Description
for Atomic_Components: Declare
that the components of an array type or object are atomic.
6.7/3
Volatile_Components
The type of aspect Volatile_Components is Boolean.
6.e/3
Aspect Description
for Volatile_Components: Declare
that the components of an array type or object are volatile.
6.8/3
6.9/3
Independent_Components
The type of aspect Independent_Components is Boolean.
6.f/3
Aspect Description
for Independent_Components: Declare
that the components of an array or record type, or an array object, are
independently addressable.
6.10/3
{
AI05-0229-1}
If any of these aspects are directly specified,
the aspect_definition
shall be a static expression. If not specified (including by inheritance),
each of these aspects is False.
7/3
{
AI95-00272-01}
{
AI05-0229-1}
An
atomic type is one
for to
which
the aspect a
pragma Atomic
is True applies.
An
atomic object (including a component) is one
for to
which
the aspect a
pragma Atomic
is True applies,
or a component of an array
for to
which
the aspect a
pragma Atomic_Components
is True for the
associated type applies, or any object
of an atomic type
, other than objects obtained
by evaluating a slice.
7.a/2
Ramification: {
AI95-00272-01}
A slice of an atomic array object is not itself
atomic. That's necessary as executing a read or write of a dynamic number
of components in a single instruction is not possible on many targets.
8/3
{
AI05-0229-1}
A
volatile type is one
for to
which
the aspect a
pragma Volatile
is True applies.
A
volatile object (including a component) is one
for to
which
the aspect a
pragma Volatile
is True applies,
or a component of an array
for to
which
the aspect a
pragma Volatile_Components
is True for the
associated type applies, or any object
of a volatile type. In addition, every atomic type or object is also
defined to be volatile. Finally, if an object is volatile, then so are
all of its subcomponents [(the same does not apply to atomic)].
8.1/3
{
AI05-0009-1}
{
AI05-0229-1}
When True, the aspects Independent and Independent_Components
specify as independently addressable the named object or component(s),
or in the case of a type, all objects or components of that type. All
atomic objects are considered to be specified as independently addressable.
8.a/3
Ramification: If
the compiler cannot guarantee that an object (including a component)
for which aspect Independent or aspect Independent_Components is True
is independently addressable from any other nonoverlapping object, then
the aspect specification must be rejected.
8.b/3
Similarly, an atomic object
(including atomic components) is always independently addressable from
any other nonoverlapping object. Any representation item which would
prevent this from being true should be rejected, notwithstanding what
this Standard says elsewhere (specifically, in the Recommended Level
of Support).
Name Resolution Rules
9/3
Legality Rules
9.1/3
10/3
{
AI05-0229-1}
It is illegal to
specify apply
either
of the aspects an
Atomic or Atomic_Components
pragma to
have
the value True for an object or type if the implementation cannot
support the indivisible reads and updates required by the
aspect pragma
(see below).
11
It is illegal to specify the Size attribute of an
atomic object, the Component_Size attribute for an array type with atomic
components, or the layout attributes of an atomic component, in a way
that prevents the implementation from performing the required indivisible
reads and updates.
12/3
{
AI05-0142-4}
{
AI05-0218-1}
If an atomic object is passed as a parameter, then
the
type of the formal parameter shall either
have
an be atomic
type
or allow pass by copy
[(that is, not be
a nonatomic by-reference type)]. If an atomic object is used as
an actual for a generic formal object of mode
in out, then the
type of the generic formal object shall be atomic. If the
prefix
of an
attribute_reference
for an Access attribute denotes an atomic object [(including a component)],
then the designated type of the resulting access type shall be atomic.
If an atomic type is used as an actual for a generic formal derived type,
then the ancestor of the formal type shall be atomic
or allow pass by copy. Corresponding rules apply to volatile objects
and types.
12.a/3
Ramification: {
AI05-0142-4}
A formal parameter allows pass by copy if it is
not aliased and it is of a type that allows pass by copy (that
is, is not a by-reference type).
12.1/3
{
AI05-0218-1}
If a volatile type is used as an actual for a generic
formal array type, then the element type of the formal type shall be
volatile.
13/3
{
AI05-0229-1}
If
an aspect a pragma
Volatile, Volatile_Components, Atomic, or Atomic_Components
is
directly specified to have the value True for applies
to a stand-alone constant object, then
the
aspect a pragma Import shall also
be specified as True for apply
to it.
13.a
Ramification: Hence, no initialization
expression is allowed for such a constant. Note that a constant that
is atomic or volatile because of its type is allowed.
13.b
Reason: Stand-alone constants that are
explicitly specified as Atomic or Volatile only make sense if they are
being manipulated outside the Ada program. From the Ada perspective the
object is read-only. Nevertheless, if imported and atomic or volatile,
the implementation should presume it might be altered externally. For
an imported stand-alone constant that is not atomic or volatile, the
implementation can assume that it will not be altered.
13.c/3
To be honest: {
AI05-0218-1}
Volatile_Components and Atomic_Components actually
are aspects of the anonymous array type; this rule only applies when
the aspect is specified directly on the constant object and not when
the (named) array type has the aspect.
13.1/3
{
AI05-0009-1}
{
AI05-0229-1}
It is illegal to specify the aspect Independent
or Independent_Components as True for a component, object or type if
the implementation cannot provide the independent addressability required
by the aspect (see 9.10).
13.2/3
{
AI05-0009-1}
{
AI05-0229-1}
It is illegal to specify a representation aspect
for a component, object or type for which the aspect Independent or Independent_Components
is True, in a way that prevents the implementation from providing the
independent addressability required by the aspect.
Static Semantics
14/3
Dynamic Semantics
15
For an atomic object (including an atomic component)
all reads and updates of the object as a whole are indivisible.
16/3
{
AI05-0117-1}
All tasks of the program (on all processors) that
read or update volatile variables see the same order of updates to the
variables. For a volatile object all reads
and updates of the object as a whole are performed directly to memory.
16.a/3
Implementation Note: {
AI05-0117-1}
To ensure this, on a multiprocessor, any read or
update of a volatile object should involve the use of an appropriate
memory barrier. This precludes any use of
register temporaries, caches, and other similar optimizations for that
object.
17
Two actions are sequential (see
9.10) if each is the read or update of the
same atomic object.
18
If a type is atomic or volatile
and it is not a by-copy type, then the type is defined to be a by-reference
type. If any subcomponent of a type is atomic or volatile, then the type
is defined to be a by-reference type.
19
If an actual parameter is atomic or volatile, and
the corresponding formal parameter is not, then the parameter is passed
by copy.
19.a
Implementation Note: Note that in the
case where such a parameter is normally passed by reference, a copy of
the actual will have to be produced at the call-site, and a pointer to
the copy passed to the formal parameter. If the actual is atomic, any
copying has to use indivisible read on the way in, and indivisible write
on the way out.
19.b
Reason: It has to be known at compile
time whether an atomic or a volatile parameter is to be passed by copy
or by reference. For some types, it is unspecified whether parameters
are passed by copy or by reference. The above rules further specify the
parameter passing rules involving atomic and volatile types and objects.
Implementation Requirements
20
The external effect of a program
(see
1.1.3) is defined to include each read
and update of a volatile or atomic object. The implementation shall not
generate any memory reads or updates of atomic or volatile objects other
than those specified by the program.
20.a
Discussion: The presumption is that volatile
or atomic objects might reside in an “active” part of the
address space where each read has a potential side-effect, and at the
very least might deliver a different value.
20.b
The rule above
and the definition of external effect are intended to prevent (at least)
the following incorrect optimizations, where V is a volatile variable:
20.c
X:= V; Y:=V; cannot be allowed to be translated
as Y:=V; X:=V;
20.d
Deleting redundant loads: X:= V; X:= V; shall
read the value of V from memory twice.
20.e
Deleting redundant stores: V:= X; V:= X; shall
write into V twice.
20.f
Extra stores: V:= X+Y; should not translate
to something like V:= X; V:= V+Y;
20.g
Extra loads: X:= V; Y:= X+Z; X:=X+B; should
not translate to something like Y:= V+Z; X:= V+B;
20.h
Reordering of loads from volatile variables:
X:= V1; Y:= V2; (whether or not V1 = V2) should not translate to Y:=
V2; X:= V1;
20.i
Reordering of stores to volatile variables:
V1:= X; V2:= X; should not translate to V2:=X; V1:= X;
21/3
{
AI05-0229-1}
If
the a pragma
Pack
aspect is True for applies
to a type any of whose subcomponents are atomic, the implementation
shall not pack the atomic subcomponents more tightly than that for which
it can support indivisible reads and updates.
21.a/3
Implementation Note: {
AI05-0009-1}
Usually, specifying aspect Pack for such a type
will be illegal as the Recommended Level of Support cannot be achieved;
otherwise, a A warning might be appropriate
if no packing whatsoever can be achieved.
Implementation Advice
22/2
{
AI95-00259-01}
A load or store of a volatile object whose size
is a multiple of System.Storage_Unit and whose alignment is nonzero,
should be implemented by accessing exactly the bits of the object and
no others.
22.a/2
Implementation Advice:
A load or store of a volatile object
whose size is a multiple of System.Storage_Unit and whose alignment is
nonzero, should be implemented by accessing exactly the bits of the object
and no others.
22.b/2
Reason: Since any
object can be a volatile object, including packed array components and
bit-mapped record components, we require the above only when it is reasonable
to assume that the machine can avoid accessing bits outside of the object.
22.c/2
Ramification: This
implies that the load or store of a volatile object that meets the above
requirement should not be combined with that of any other object, nor
should it access any bits not belonging to any other object. This means
that the suitability of the implementation for memory-mapped I/O can
be determined from its documentation, as any cases where the implementation
does not follow Implementation Advice must be documented.
23/2
{
AI95-00259-01}
A load or store of an atomic object should, where
possible, be implemented by a single load or store instruction.
23.a/2
Implementation Advice:
A load or store of an atomic object
should be implemented by a single load or store instruction.
24
9 An imported volatile or atomic constant
behaves as a constant (i.e. read-only) with respect to other parts of
the Ada program, but can still be modified by an “external source.”
Incompatibilities With Ada 83
24.a
Pragma Atomic replaces Ada
83's pragma Shared. The name “Shared” was confusing, because
the pragma was not used to mark variables as shared.
Wording Changes from Ada 95
24.b/2
{
AI95-00259-01}
Added Implementation Advice to clarify the meaning
of Atomic and Volatile in machine terms. The documentation that this
advice applies will make the use of Ada implementations more predictable
for low-level (such as device register) programming.
24.c/2
{
AI95-00272-01}
Added wording to clarify that a slice of an object
of an atomic type is not atomic, just like a component of an atomic type
is not (necessarily) atomic.
Incompatibilities With Ada 2005
24.d/3
{
AI05-0218-1}
Correction: Plugged
a hole involving volatile components of formal types when the formal
type's component has a non-volatile type. This was done by making certain
actual types illegal for formal derived and formal array types; these
types were allowed for Ada 95 and Ada 2005.
Extensions to Ada 2005
24.e/3
{
AI05-0009-1}
{
AI05-0229-1}
Aspects Independent and Independent_Components
are new; they eliminate ambiguity about independent addressability.
24.f/3
{
AI05-0229-1}
Aspects Atomic, Atomic_Components, Volatile, and
Volatile_Components are new; pragmas
Atomic, Atomic_Components, Volatile, and Volatile_Components are now
obsolescent.
Wording Changes from Ada 2005
24.g/3
{
AI05-0117-1}
Revised the definition of volatile to eliminate
overspecification and simply focus on the root requirement (that all
tasks see the same view of volatile objects). This is not an inconsistency;
"memory" arguably includes on-chip caches so long as those
are kept consistent. Moreover, it is difficult to imagine a program that
could tell the difference.
24.h/3
{
AI05-0142-4}
Added wording to take explicitly aliased parameters
(see 6.1) into account when determining the
legality of parameter passing of volatile and atomic objects.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe