Version 1.4 of ai05s/ai05-0201-1.txt
!standard 9.10(1/3) 11-03-11 AI05-0201-1/02
!standard C.6(22/2)
!standard C.6(23/2)
!class binding interpretation 10-02-12
!status Amendment 2012 11-03-11
!status ARG Approved 7-0-0 11-02-20
!status work item 10-02-12
!status received 09-11-10
!priority Low
!difficulty Hard
!qualifier Omission
!subject Independence and components of atomic objects
!summary
Components of an atomic composite object are not necessarily
independently-addressable.
!question
Given:
type AR is record
F1, F2, F3, F4, F5, F6, F7, F8 : Boolean;
Q : Interfaces.Unsigned_8;
R : Interfaces.Unsigned_16; --
end record;
for AR'Size use 32;
for AR use record
F1 at 0 range 0 .. 0;
...
F8 at 0 range 7 .. 7;
Q at 0 range 8 .. 15;
R at 0 range 16 .. 31;
end record;
X : AR;
for X'Address use ...;
pragma Atomic (X);
...
X.F3 := True; --
if X.F5 then --
...
The above is a typical usage for declaring a register of a memory mapped I/O
device on a 32-bit machine. However, while it is natural and tempting to set the
bit in the register as above, typically such I/O accesses need to use the full
register width.
The language suggests this behavior in the Implementation Advice C.6(22/2) and
C.6(23/2).
However, consider:
type BR is record
Q1, Q2, Q3, Q4 : Interfaces.Unsigned_8;
end record;
for BR'Size use 32;
Y : BR;
for Y'Address use ...;
pragma Atomic (T);
...
According to 9.10(1/3) [as modified by AI05-0009-1], these components would be
independently addressible. Thus they are required to be accessible by separate
tasks without interference, and following the advice of C.6(22-23/2) is
impossible (only a portion of the object is being written, which would violate
C.6(22)).
Should pragma Atomic on a composite object or type imply components are not
independently addressable? (No, but it can effect whether the components are
independently addressable.)
!recommendation
(See Summary.)
!wording
Modify 9.10(1) as changed by AI05-0009-1:
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 non-confirming representation item is used to specify
packing, record layout, Component_Size, {Atomic, }or convention, in which
case it is unspecified whether the parts are independently addressable.
Add to AARM 9.10(1.d/3):
Note, however, that the components of an atomic object are not necessarily
atomic.
!discussion
The original suggestion of requiring that the components of an atomic
object are not independently addressable makes no sense. We only define
what it means to be independently addressable; there are no requirements
on objects that aren't defined to be independently addressable.
Probably what the questioner meant was that the wording should not require
independent addressability of components of an atomic object. Such a
requirement cannot be met while still following the Implementation Advice
C.6(23/2); since language requirements are stronger than Implementation
Advice, that advice has to be ignored. That's definitely not what we want.
So, we eliminate any requirement that non-atomic components of an atomic
object are independently addressible. No such requirement was ever intended.
Of course, an implementation can still treat such components as addressable,
and ignore the Implementation Advice of C.6(22-23/2). Whether that is an
acceptable implementation is up to their customers.
[Editor's note: I find the Implementation Advice C.6(22/2) slightly suspicious
in this case, as it's not clear that the entire atomic object is loaded or
stored for a reference to a portion of it. It's fairly clear that the intent was
that that would happen for atomic objects, but not necessarily volatile objects.
Perhaps we need to strengthen the IA a bit for this case?? (I'm not too excited
about trying to do that, given how difficult it was to agree on this IA the last
time.) Note that even if we do change the IA, we still have to eliminate the
requirement for independence, because that would always take precedence over the
IA. Also, implementations are always allowed to go beyond the IA, but they can't
ignore language rules to do so.]
!corrigendum 9.10(1/3)
Replace the paragraph:
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 non-confirming representation item is used to specify
packing, record layout, Component_Size, or convention, in which case
it is unspecified whether the parts are independently addressable.
by:
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 non-confirming representation item is used to specify
packing, record layout, Component_Size, Atomic, or convention, in which case
it is unspecified whether the parts are independently addressable.
!ACATS Test
An ACATS B-Test should be created that is similar to the example in the
question.
!appendix
!topic Semantics of operations on components of atomic records
!reference C.6. 9.10
!from Geert Bosch 09-11-10
!discussion
Given:
type AR is record
F1, F2, F3, F4, F5, F6, F7, F8 : Boolean;
Q : Interfaces.Unsigned_8;
R : Interfaces.Unsigned_16; -- Reserved
end record;
for AR'Size use 32;
for AR use record
F1 at 0 range 0 .. 0;
...
F8 at 0 range 7 .. 7;
Q at 0 range 8 .. 15;
R at 0 range 16 .. 31;
end record;
X : AR;
for X'Address use ...;
pragma Atomic (X);
...
X.F3 := True; -- Enable F3
if X.F5 then -- Check some status bit
...
The above is a typical usage for declaring a register of a memory mapped I/O
device on a 32-bit machine. However, while it is natural and tempting to set the
bit in the register as above, typically such I/O accesses need to use the full
register width. This would require something like:
declare
Temp : AR;
begin
Temp := X;
X.F3 := True;
X := Temp;
end;
even reads need to be written as:
declare
Temp : AR;
begin
Temp := X;
if Temp.F5 then
...
end if;
end;
in order to avoid potential accesses using 8 bit or 16 bit reads.
As it is clear that on a typical byte-addressable machine F3 and F5 would not be
independently addressable, and in general it is implementation-defined wether
any components of a record with representation clauses are independently
addressable. Even the natural (or naive) way of accessing components of AR may
well produce the desired 32-bit reads and writes, depending on compiler version,
optimization settings and target machine.
For consistency, it seems that the most helpful semantics are that any read of
an atomic object or component thereof is a read of the whole of the atomic
object, and similarly for writes.
However, given:
type BR is record
Q1, Q2, Q3, Q4 : Interfaces.Unsigned_8;
end record;
for BR'Size use 32;
Y : BR;
for Y'Address use ...;
pragma Atomic (T);
...
According to C.5, Q1 through Q4 would be independently addressable, which
combined with their volatility would imply that accesses should be byte
accesses. Unlike the first example, which has come up in actual code and let to
hard to find bugs, this second example is contrived.
Question: should pragma Atomic on a composite object or type
imply components are not independently addressable?
Note that even if components are not independently addressable, accessing an
atomic object as a whole preserves sequentiality, so there is no problem with
shared variables in this respect.
****************************************************************
Questions? Ask the ACAA Technical Agent