!standard 9.10(1/3) 10-02-12 AI05-0201-1/01 !standard C.6(22/2) !standard C.6(23/2) !class binding interpretation 10-02-12 !status work item 10-02-12 !status received 09-09-24 !priority Low !difficulty Hard !qualifier Omission !subject Independence and components of atomic objects !summary ** TBD ** !question 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. 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? (Not exactly.) !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): This does not apply to the components of the atomic object, however. !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 3.9.3(4/2) !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. ****************************************************************