Contents Index Search Previous Next
C.6 Shared Variable Control
1
[This clause specifies representation pragmas
that control the use of shared variables.]
Syntax
2
The form for
pragmas Atomic, Volatile, Atomic_Components, and Volatile_Components
is as follows:
3
pragma Atomic(
local_name);
4
pragma Volatile(
local_name);
5
pragma Atomic_Components(
array_local_name);
6
pragma Volatile_Components(
array_local_name);
7
{atomic} An
atomic type is one to which a pragma Atomic applies. An
atomic
object (including a component) is one to which a pragma Atomic applies,
or a component of an array to which a pragma Atomic_Components applies,
or any object of an atomic type.
8
{volatile} A
volatile type is one to which a pragma Volatile applies. A
volatile
object (including a component) is one to which a pragma Volatile applies,
or a component of an array to which a pragma Volatile_Components 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)].
Name Resolution Rules
9
The local_name
in an Atomic or Volatile pragma shall resolve to denote either an object_declaration,
a non-inherited component_declaration,
or a full_type_declaration. The
array_local_name in an Atomic_Components
or Volatile_Components pragma shall resolve to denote the declaration
of an array type or an array object of an anonymous type.
Legality Rules
10
{indivisible} It
is illegal to apply either an Atomic or Atomic_Components pragma to an
object or type if the implementation cannot support the indivisible reads
and updates required by the 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
If an atomic object is passed as a parameter,
then the type of the formal parameter shall either be atomic 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.
13
If a pragma Volatile, Volatile_Components, Atomic,
or Atomic_Components applies to a stand-alone constant object, then a
pragma Import shall also 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.
Static Semantics
14
{representation pragma (Atomic)
[partial]} {pragma, representation
(Atomic) [partial]} {representation
pragma (Volatile) [partial]} {pragma,
representation (Volatile) [partial]} {representation
pragma (Atomic_Components) [partial]} {pragma,
representation (Atomic_Components) [partial]} {representation
pragma (Volatile_Components) [partial]} {pragma,
representation (Volatile_Components) [partial]} These
pragmas are representation pragmas
(see
13.1).
Dynamic Semantics
15
For an atomic object (including an atomic component)
all reads and updates of the object as a whole are indivisible.
16
For a volatile object all reads and updates of
the object as a whole are performed directly to memory.
16.a
Implementation Note: This
precludes any use of register temporaries, caches, and other similar
optimizations for that object.
17
{sequential (actions)}
Two actions are sequential (see
9.10)
if each is the read or update of the same atomic object.
18
{by-reference type (atomic
or volatile) [partial]} 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
{external effect (volatile/atomic
objects) [partial]} 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
If a pragma Pack 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
Implementation Note: A
warning might be appropriate if no packing whatsoever can be achieved.
22
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
22.a
{incompatibilities with Ada
83} Pragma Atomic replaces Ada 83's pragma Shared.
The name ``Shared'' was confusing, because the pragma was not used to
mark variables as shared.
Contents Index Search Previous Next Legal