Section: 6.9.2 [intro.multithread], 32.5.8 [atomics.types.generic], 17.13 [support.runtime] Status: SG1 Submitter: Geoffrey Romer Opened: 2015-05-29 Last modified: 2018-03-15
Priority: 3
View all other issues in [intro.multithread].
View all issues with SG1 status.
Discussion:
The concurrency libraries specified in clauses 29 and 30 do not adequately specify how they relate to the concurrency model specified in 6.9.2 [intro.multithread]. In particular:
6.9.2 [intro.multithread] specifies "atomic objects" as having certain properties. I can only assume that instances of the classes defined in Clause 29 are intended to be "atomic objects" in this sense, but I can't find any wording to specify that, and it's genuinely unclear whether Clause 30 objects are atomic objects. In fact, on a literal reading the C++ Standard doesn't appear to provide any portable way to create an atomic object, or even determine whether an object is an atomic object. (It's not clear if the term "atomic object" is actually needed, given that atomic objects can have non-atomic operations, and non-atomic objects can have atomic operations. But even if the term itself goes away, there still needs to be some indication that Clause 29 objects have the properties currently attributed to atomic objects). Similarly, 6.9.2 [intro.multithread] uses "atomic operation" as a term of art, but the standard never unambiguously identifies any operation as an "atomic operation" (although in one case it unambiguously identifies an operation that is not atomic). It does come close in a few cases, but not close enough:6.9.2 [intro.multithread]/p7 could be read to imply that "synchronization operations" in Clauses 29 and 30 are also atomic operations. However, that's vague and indirect, and somewhat belied by 32.6.4.2 [thread.mutex.requirements.mutex]/p5, which specifies that mutex lock and unlock operations "behave as atomic operations", but only "for purposes of determining the existence of a data race". Furthermore, not a single operation in Clause 29 explicitly identifies itself as a "synchronization operation".
32.5.8 [atomics.types.generic]/p4 states in part that "There shall be a specialization atomic<bool>
which provides the general atomic operations as specified in 29.6.1", but read in context, "general atomic operations"
appears to be a loose synonym for "general operations on atomic types" as defined in [atomics.types.operations.general],
rather than a use of "atomic object" as Words of Power. Incidentally, "atomic type" is never satisfactorily defined either
(although the <atomic>
synopsis comes close).
17.13 [support.runtime]/p10 specifies exactly which operations are "plain lock-free atomic operations", but in a standard where an "integral constant expression" isn't necessarily a "constant expression", I do not feel safe assuming that a "plain lock-free atomic operation" is an "atomic operation".
Hans Boehm tells me the operations with "atomically" in the Effects element are intended to be atomic operations, but since "atomic operation" is a term of art (e.g. in 6.9.2 [intro.multithread]/p27.4), I think this needs to be spelled out rather than assumed. Furthermore, this does not help with 32.5.11 [atomics.fences], or anything in Clause 30.
[2018-03 JAX; Geoffrey comments in behalf of SG1]
SG1 consensus is that operations outside clause 32 are not "atomic operations", and objects of types defined outside clause 32 are not "atomic objects". "Synchronization operations" are operations which act as endpoints of primitive edges of partial orders other than sequenced-before, but it may make more sense to just drop that term and inline the definition, so to speak.
We would welcome a paper to make those definitions more explicit, and revise the wording as needed to be consistent with those definitions.Proposed resolution: