Annotated Ada Reference ManualLegal Information
Contents   Index   References   Search   Previous   Next 

C.6 Shared Variable Control

1/3
{AI05-0229-1} [This clause defines specifies representation aspects pragmas that control the use of shared variables.] 
Paragraphs 2 through 6 were moved to Annex J, “Obsolescent Features”. 

Syntax

2/3
{AI05-0229-1} The form for pragmas Atomic, Volatile, Atomic_Components, and Volatile_Components is as follows: 
3/3
  pragma Atomic(local_name);
4/3
  pragma Volatile(local_name);
5/3
  pragma Atomic_Components(array_local_name);
6/3
  pragma Volatile_Components(array_local_name);

Static Semantics

6.1/3
  {AI05-0229-1} For an object_declaration, a component_declaration, or a full_type_declaration, the following representation aspects may be specified:
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
  {AI05-0229-1} For a full_type_declaration of an array type (including the anonymous type of an object_declaration of an anonymous array object), the following representation aspects may be specified:
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
  {AI05-0229-1} For a full_type_declaration (including the anonymous type of an object_declaration of an anonymous array object), the following representation aspect may be specified:
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). 
Paragraph 9 was moved to Annex J, “Obsolescent Features”. 

Name Resolution Rules

9/3
{AI05-0229-1} 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

9.1/3
  {AI05-0229-1} If aspect Independent_Components is specified for a full_type_declaration, the declaration shall be that of an array or record type.
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.
Paragraph 14 was moved to Annex J, “Obsolescent Features”. 

Static Semantics

14/3
 {AI05-0229-1} 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/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.
NOTES
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.

Contents   Index   References   Search   Previous   Next 
Ada-Europe Ada 2005 and 2012 Editions sponsored in part by Ada-Europe