C.6 Shared Variable Control
This subclause defines representation aspects that
control the use of shared variables.
Static Semantics
Atomic
The type of aspect Atomic is Boolean.
Independent
The type of aspect Independent is Boolean.
Volatile
The type of aspect Volatile is Boolean.
Full_Access_Only
The type of aspect Full_Access_Only is Boolean.
Atomic_Components
The type of aspect Atomic_Components is Boolean.
Volatile_Components
The type of aspect Volatile_Components is Boolean.
Independent_Components
The type of aspect Independent_Components is Boolean.
If any of these aspects are directly specified,
the
aspect_definition
shall be a static expression. If not specified for a type (including
by inheritance), the Atomic, Atomic_Components, and Full_Access_Only
aspects are False. If any of these aspects are specified True for a type,
then the corresponding aspect is True for all objects of the type. If
the Atomic aspect is specified True, then the aspects Volatile, Independent,
and Volatile_Component (if defined) are True; if the Atomic_Components
aspect is specified True, then the aspects Volatile, Volatile_Components,
and Independent_Components are True. If the Volatile aspect is specified
True, then the Volatile_Components aspect (if defined) is True, and vice
versa. When not determined by one of the other aspects, or for an object
by its type, the Volatile, Volatile_Components, Independent, and Independent_Components
aspects are False.
An
atomic type is one
for which the aspect Atomic is True. An
atomic object (including
a component) is one for which the aspect Atomic is True, or a component
of an array for which the aspect Atomic_Components is True for the associated
type, or any object of an atomic type, other than objects obtained by
evaluating a slice.
A
volatile type is one
for which the aspect Volatile is True. A
volatile object (including
a component) is one for which the aspect Volatile is True, or a component
of an array for which the aspect Volatile_Components is True for the
associated type, 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).
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 and aliased objects are considered to be specified as
independently addressable.
The Full_Access_Only aspect shall not be specified
unless the associated type or object is volatile (or atomic). A
full
access type is any atomic type, or a volatile type for which the
aspect Full_Access_Only is True.
A
full access
object (including a component) is any atomic object, or a volatile object
for which the aspect Full_Access_Only is True for the object or its type.
A Full_Access_Only aspect is illegal if any subcomponent of the object
or type is a full access object or is of a generic formal type.
Legality Rules
If aspect Independent_Components is specified for
a
full_type_declaration,
the declaration shall be that of an array or record type.
It is illegal to specify either
of the aspects Atomic or Atomic_Components to have the value True for
an object or type if the implementation cannot support the indivisible
and independent reads and updates required by the aspect (see below).
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
and independent reads and updates.
If an atomic object is passed as a parameter, then
the formal parameter shall either have an atomic type or allow pass by
copy. 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.
Corresponding rules apply to volatile objects and to full access objects.
If a nonatomic subcomponent of a full access object
is passed as an actual parameter in a call then the formal parameter
shall allow pass by copy (and, at run time, the parameter shall be passed
by copy). A nonatomic subcomponent of a full access object shall not
be used as an actual for a generic formal of mode
in out. The
prefix of
an
attribute_reference
for an Access attribute shall not denote a nonatomic subcomponent of
a full access object.
If the Atomic, Atomic_Components, Volatile, Volatile_Components,
Independent, Independent_Components, or Full_Access_Only aspect is True
for a generic formal type, then that aspect shall be True for the actual
type. 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. A corresponding
rule applies to volatile types and similarly to full access types.
If a type with volatile components is used as an
actual for a generic formal array type, then the components of the formal
type shall be volatile. Furthermore, if the actual type has atomic components
and the formal array type has aliased components, then the components
of the formal array type shall also be atomic. A corresponding rule applies
when the actual type has volatile full access components.
If an aspect Volatile, Volatile_Components, Atomic,
or Atomic_Components is directly specified to have the value True for
a stand-alone constant object, then the aspect Import shall also be specified
as True for it.
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).
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.
Dynamic Semantics
For an atomic object (including an atomic component)
all reads and updates of the object as a whole are indivisible.
All tasks of the program (on all processors) that
read or update volatile variables see the same order of updates to the
variables. A use of an atomic variable or other mechanism may be necessary
to avoid erroneous execution and to ensure that access to nonatomic volatile
variables is sequential (see
9.10).
Two actions are sequential (see
9.10) if each is the read or update of the
same atomic object.
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.
If an actual parameter is atomic or volatile, and
the corresponding formal parameter is not, then the parameter is passed
by copy.
All reads of or writes to any nonatomic subcomponent
of a full access object are performed by reading and/or writing all of
the nearest enclosing full access object.
Implementation Requirements
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. However, there may be target-dependent
cases where reading or writing a volatile but nonatomic object (typically
a component) necessarily involves reading and/or writing neighboring
storage, and that neighboring storage can overlap a volatile object.
This paragraph was
deleted.
Implementation Permissions
Within the body of an instance of a generic unit
that has a formal type T that is not atomic and an actual type
that is atomic, if an object O of type T is declared and
explicitly specified as atomic, the implementation may introduce an additional
copy on passing O to a subprogram with a parameter of type T
that is normally passed by reference. A corresponding permission applies
to volatile parameter passing.
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,
except in the case of a volatile but nonatomic subcomponent of an atomic
object.
A load or store of an atomic object should, where
possible, be implemented by a single load or store instruction.
NOTE 1 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”.
NOTE 2 Specifying the Pack aspect
cannot override the effect of specifying an Atomic or Atomic_Components
aspect.
NOTE 3 When mapping an Ada object
to a memory-mapped hardware register, the Ada object can be declared
atomic to ensure that the compiler will read and write exactly the bits
of the register as specified in the source code and no others.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe