<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=US-ASCII">
<title>More Collected Issues with Atomics</title>
</head>
<body>
<h1>More Collected Issues with Atomics</h1>

<p>
ISO/IEC JTC1 SC22 WG21 N2925 = 09-0115 - 2009-08-02
</p>

<p>
Lawrence Crowl, crowl@google.com, Lawrence@Crowl.org
</p>

<p>

<a href="#introduction">Introduction</a><br>
<a href="#header">Headers</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#header_issues"> Issues</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#LWG1145">LWG 1145, UK 312: inappropriate headers for atomics</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#header_wording">Wording</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#headers">17.6.1.2 Headers [headers]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#atomics.general">29.1 General [atomics.general]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#atomics.syn">29.2 Header <code>&lt;cstdatomic&gt;</code> synopsis [atomics.syn]</a><br>
<a href="#concept_issues">Conceptification</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#concept_issues">Issues</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#UK311">UK 311: Conceptification</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#LWG1143">US 87, LWG 1143: Atomic operations library not concept enabled</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#923">LWG 923: atomics with floating-point</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#LWG924">LWG 924: structs with internal padding</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#concept_wording">Wording</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#atomics.types.generic_concept">29.5.3 Generic Types [atomic.types.generic]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#atomics.types.operations">29.6 Operations on Atomic Types [atomics.types.operations]</a><br>
<a href="#fence">Fences</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#fence_issues">Issues</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#LWG926">LWG 926: Sequentially consistent fences, relaxed operations and modification order</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#UK313">UK 313: seq_cst Fences</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#fence_wording">Wording</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#atomics.order">29.3 Order and Consistency [atomics.order]</a><br>
<a href="#lockfree">Lock Free</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#lockfree_issues">Issues</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#1146">LWG 1146, US 88: "lockfree" does not say enough</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#lockfree_wording">Wording</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#atomics.lockfree">29.4 Lock-free Property [atomics.lockfree]</a><br>
<a href="#typedef">Typedefs</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#typedef_issues">Issues</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#937">LWG 937, US 89</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#LWG943">LWG 943: <code>ssize_t</code> undefined</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#typedef_wording">Wording</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#atomics.types.integral_typedef">29.5.1 Integral Types [atomics.types.integral]</a><br>
<a href="#volatile">Volatile</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#volatile_issues">Issues</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#LWG1147">LWG 1147, US 90: non-volatile atomic functions</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#LWG908">LWG 908: Deleted assignment operators for atomic types must be volatile</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#volatile_wording">Wording</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#atomics">29 Atomic operations library [atomics]</a><br>
<a href="#memcmpxchg">Memory Order of Compare Exchange</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#memcmpxchg_issues">Issues</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US91">US 91: Failed Compare Exchange</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#LWG1043"></a>LWG 1043: Response to US 91<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#US92">US 92: RMW with Consume</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#memcmpxchg_wording">Wording</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#atomics.types.operations">29.6 Operations on Atomic Types [atomics.types.operations]</a><br>
<a href="#flag">Atomic Flag</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#flag_issues">Issues</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#WG14">LWG ?, WG14: Flag Initialization</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#flag_wording">Wording</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#atomics.flag">29.7 Flag Type and Operations [atomics.flag]</a><br>
<a href="#derivation">Derivation</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#derivation_issues">Issues</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#LWG944"></a>LWG 944: <code>atomic&lt;bool&gt;</code> derive from <code>atomic_bool</code>?<br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#derivation_wording">Wording</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#atomics.types.generic_derivation">29.5.3 Generic Types [atomic.types.generic]</a><br>
<a href="#const">Const Load</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#const_issues">Issues</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#LWG879">LWG 879: Atomic load const qualification</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#const_wording">Wording</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#atomics.types.address">29.5.2 Address Type [atomic.types.address]</a><br>
<a href="#parameter">Atomic Exchange Parameter</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#parameter_issues">Issues</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#880">LWG 880: Missing atomic exchange parameter</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#parameter_wording">Wording</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#atomics.syn">29.2 Header <code>&lt;cstdatomic&gt;</code> synopsis [atomic.syn]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#atomics.types.integral_parameter">29.5.1 Integral Types [atomics.types.integral]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#atomics.types.address_parameter">29.5.2 Address Type [atomics.types.address]</a><br>

</p>

<h2><a name="introduction">Introduction</a></h2>

<p>
This paper presents several topics.
Each topic presents the related issues,
then presents formal wording changes to various sections
in the working draft.
Proposed resolutions in the issues
are <strong>not</strong> to be applied.
Only the wording in paper sections
with working draft section titles
shall be applied.
</p>

<h2><a name="header">Headers</a></h2>
<h3><a name="header_issues"> Issues</a></h3>

<h4><a name="LWG1145">LWG 1145, UK 312: inappropriate headers for atomics</a></h4>

<p><b>Status:</b> New
</p>

<p><b>Submitter:</b> LWG
</p>

<p><b>Discussion:</b>
The contents of the <code>&lt;stdatomic.h&gt;</code> header are not listed anywhere,
and <code>&lt;cstdatomic&gt;</code> is listed as a C99 header in chapter 17.
If we intend to use these for compatibility with a future C standard,
we should not use them now.
</p>

<p><b>Proposed resolution:</b>
Remove <code>&lt;cstdatomic&gt;</code> from the C99 headers in table 14.
Add a new header <code>&lt;atomic&gt;</code> to the headers in table 13.
Update chapter 29 to remove reference to <code>&lt;stdatomic.h&gt;</code>
and replace the use of <code>&lt;cstdatomic&gt;</code> with <code>&lt;atomic&gt;</code>.
</p>

<p><i>[
If and when WG14 adds atomic operations to C
we can add corresponding headers to table 14 with a TR.
]</i></p>

<p><b>Committee:</b>
May be resolvable with a footnote for clarity
stating that the header is defined where it exists. 
</p>


<h3><a name="header_wording">Wording</a></h3>

<h4><a name="headers">17.6.1.2 Headers [headers]</a></h4>

<p>
Edit table 13 as follows.
</p>

<blockquote>
<table>
<tbody>
<caption>Table 13 &mdash; C++ library headers</caption>
<tr><td><code>&lt;algorithm&gt;</code></td><td><code>&lt;forward_list&gt;</code></td><td><code>&lt;iterator_concepts&gt;</code></td><td><code>&lt;queue&gt;</code></td><td><code>&lt;system_error&gt;</code></td></tr>
<tr><td><code>&lt;array&gt;</code></td><td><code>&lt;fstream&gt;</code></td><td><code>&lt;limits&gt;</code></td><td><code>&lt;random&gt;</code></td><td><code>&lt;threads&gt;</code></td></tr>
<tr><td><code>&lt;bitset&gt;</code></td><td><code>&lt;functional&gt;</code></td><td><code>&lt;list&gt;</code></td><td><code>&lt;ratio&gt;</code></td><td><code>&lt;tuple&gt;</code></td></tr>
<tr><td><code>&lt;chrono&gt;</code></td><td><code>&lt;future&gt;</code></td><td><code>&lt;locale&gt;</code></td><td><code>&lt;regex&gt;</code></td><td><code>&lt;typeinfo&gt;</code></td></tr>
<tr><td><code>&lt;codecvt&gt;</code></td><td><code>&lt;initializer_list&gt;</code></td><td><code>&lt;map&gt;</code></td><td><code>&lt;set&gt;</code></td><td><code>&lt;type_traits&gt;</code></td></tr>
<tr><td><code>&lt;complex&gt;</code></td><td><code>&lt;iomanip&gt;</code></td><td><code>&lt;memory&gt;</code></td><td><code>&lt;sstream&gt;</code></td><td><code>&lt;unordered_map&gt;</code></td></tr>
<tr><td><code>&lt;concepts&gt;</code></td><td><code>&lt;ios&gt;</code></td><td><code>&lt;memory_concepts&gt;</code></td><td><code>&lt;stack&gt;</code></td><td><code>&lt;unordered_set&gt;</code></td></tr>
<tr><td><code>&lt;condition_variable&gt;</code></td><td><code>&lt;iosfwd&gt;</code></td><td><code>&lt;mutex&gt;</code></td><td><code>&lt;stdexcept&gt;</code></td><td><code>&lt;utility&gt;</code></td></tr>
<tr><td><code>&lt;container_concepts&gt;</code></td><td><code>&lt;iostream&gt;</code></td><td><code>&lt;new&gt;</code></td><td><code>&lt;streambuf&gt;</code></td><td><code>&lt;valarray&gt;</code></td></tr>
<tr><td><code>&lt;deque&gt;</code></td><td><code>&lt;istream&gt;</code></td><td><code>&lt;numeric&gt;</code></td><td><code>&lt;string&gt;</code></td><td><code>&lt;vector&gt;</code></td></tr>
<tr><td><code>&lt;exception&gt;</code></td><td><code>&lt;iterator&gt;</code></td><td><code>&lt;ostream&gt;</code></td><td><code>&lt;strstream&gt;</code></td><td><ins><code>&lt;atomic&gt;</code></ins></td></tr>
</tbody>
</table>
</blockquote>

<p>
Edit table 14 as follows.
</p>

<blockquote>
<table>
<tbody>
<caption>Table 14 &mdash; C++ headers for C library facilities</caption>
<tr><td><code>&lt;cassert&gt;</code></td><td><code>&lt;cinttypes&gt;</code></td><td><code>&lt;csignal&gt;</code></td><td><code>&lt;cstdio&gt;</code></td><td><code>&lt;cwchar&gt;</code></td></tr>
<tr><td><code>&lt;ccomplex&gt;</code></td><td><code>&lt;ciso646&gt;</code></td><td><code>&lt;cstdarg&gt;</code></td><td><code>&lt;cstdlib&gt;</code></td><td><code>&lt;cwctype&gt;</code></td></tr>
<tr><td><code>&lt;cctype&gt;</code></td><td><code>&lt;climits&gt;</code></td><td><del><code>&lt;cstdatomic&gt;</code></del></td><td><code>&lt;cstring&gt;</code></td></tr>
<tr><td><code>&lt;cerrno&gt;</code></td><td><code>&lt;clocale&gt;</code></td><td><code>&lt;cstdbool&gt;</code></td><td><code>&lt;ctgmath&gt;</code></td></tr>
<tr><td><code>&lt;cfenv&gt;</code></td><td><code>&lt;cmath&gt;</code></td><td><code>&lt;cstddef&gt;</code></td><td><code>&lt;ctime&gt;</code></td></tr>
<tr><td><code>&lt;cfloat&gt;</code></td><td><code>&lt;csetjmp&gt;</code></td><td><code>&lt;cstdint&gt;</code></td><td><code>&lt;cuchar&gt;</code></td></tr>
</tbody>
</table>
</blockquote>


<h4><a name="atomics.general">29.1 General [atomics.general]</a></h4>

<p>
Edit table 118 as follows.
</p>

<blockquote>
<table>
<tbody>
<caption>Table 118 &mdash; Atomics library summary</caption>
<tr><th>Subclause</th><th>Header(s)</th></tr>
<tr><td>29.3 Order and Consistency</td></tr>
<tr><td>29.4 Lock-free Property</td></tr>
<tr><td>29.5 Atomic Types</td>
<td><code><del>&lt;cstdatomic&gt;, &lt;stdatomic.h&gt;</del>
<ins>&lt;atomic&gt;</ins></code></td></tr>
<tr><td>29.6 Operations on Atomic Types</td></tr>
<tr><td>29.7 Flag Type and Operations</td></tr>
</table>
</blockquote>

<h4><a name="atomics.syn">29.2 Header <code>&lt;cstdatomic&gt;</code> synopsis [atomics.syn]</a></h4>

<p>
Edit the section title as follows.
</p>

<blockquote>
<p>
<b>29.2 Header <code><del>&lt;cstdatomic&gt;</del>
<ins>&lt;atomic&gt;</ins></code> synopsis [atomics.syn]</b>
</p>
</blockquote>

<h2><a name="concept_issues">Conceptification</a></h2>

<p>
While the July 2009 meeting of the committee
voted to remove concepts from the C++0x effort,
the definition of the <code>atomic</code> template
must still be clear in its documentation about the concepts it uses.
</p>

<h3><a name="concept_issues">Issues</a></h3>

<h4><a name="UK311">UK 311: Conceptification</a></h4>

<p><b>Comment:</b>
Atomic types cannot be used generically in a constrained template.
</p>

<p><b>Suggestion:</b>
Provide constraints for the atomics library, clause 29.
</p>

<h4><a name="LWG1143">US 87, LWG 1143: Atomic operations library not concept enabled</a></h4>

<p><b>Status:</b> New</p>

<p><b>Submitter:</b> LWG</p>

<p><b>Discussion:</b>
The atomics chapter is not concept enabled.
</p>

<p>
Needs to also consider issues
LWG 923 and
LWG 924.
</p>

<h4><a name="923">LWG 923: atomics with floating-point</a></h4>

<p><b>Status:</b> Open</p>

<p><b>Submitter:</b> Herb Sutter</p>

<p><b>Discussion:</b>
Right now, C++0x doesn't have <code>atomic&lt;float&gt;</code>.
We're thinking of adding the words to support it for TR2
(note: that would be slightly post-C++0x).
If we need it, we could probably add the words.
</p>

<p><b>Proposed resolutions:</b>
Using <code>atomic&lt;FP&gt;::compare_exchange</code>
(weak or strong) should be either:
</p>

<ol>
<li>ill-formed, or</li>
<li>well-defined.</li>
</ol>

<p>
I propose Option 1 for C++0x for expediency.
If someone wants to argue for Option 2,
they need to say what exactly they want <code>compare_exchange</code>
to mean in this case
(IIRC, C++0x doesn't even assume IEEE 754).
</p>

<p><i>[ Summit: ]</i></p>

<blockquote>
<p>
Move to open. Blocked until concepts for atomics are addressed.
</p>
</blockquote>

<p><i>[ Post Summit Anthony adds: ]</i></p>

<blockquote>
<p>
Recommend NAD.
C++0x does have <code>std::atomic&lt;float&gt;</code>,
and both <code>compare_exchange_weak</code> and <code>compare_exchange_strong</code>
are well-defined in this case.
Maybe change the note in 29.6 [atomics.types.operations] paragraph 20 to:
</p>

<blockquote>
<p>
[<i>Note:</i>
The effect of the compare-and-exchange operations is
</p>
<blockquote><pre><code>
if (!memcmp(object,expected,sizeof(*object)))
    *object = desired;
else
    *expected = *object;
</code></pre></blockquote>

<p>
This may result in failed comparisons for values that compare equal
if the underlying type has padding bits
or alternate representations of the same value.
&mdash;<i>end note</i>]
</p>
</blockquote>

</blockquote>

<p><b>Proposed resolution:</b>
Change the note in 29.6 [atomics.types.operations] paragraph 20 to:
</p>

<blockquote>
<p>
[<i>Note:</i> The effect of the compare-and-exchange operations is
</p>
<blockquote><pre><code>
if (<del>*object == *expected</del>
    <ins>!memcmp(object,expected,sizeof(*object))</ins>)
    *object = desired;
else
    *expected = *object;
</code></pre></blockquote>

<p><ins>
This may result in failed comparisons for values that compare equal
if the underlying type has padding bits
or alternate representations of the same value.</ins>
&mdash;<i>end note</i>]
</p>
</blockquote>

<h4><a name="LWG924">LWG 924: structs with internal padding</a></h4>

<p><b>Status:</b> Open
</p>

<p><b>Submitter:</b> Herb Sutter
</p>

<p><b>Discussion:</b>
Right now,
the <code>compare_exchange_weak</code> loop
should rapidly converge on the padding contents.
But <code>compare_exchange_strong</code>
will require a bit more compiler work
to ignore padding for comparison purposes.
</p>

<p>
Note that this isn't a problem for structs with no padding,
and we do already have one portable way
to ensure that there is no padding that covers the key use cases:
Have elements be the same type.
I suspect that the greatest need is for a structure of two pointers,
which has no padding problem.
I suspect the second need is a structure of a pointer
and some form of an integer.
If that integer is <code>intptr_t</code>, there will be no padding.
</p>

<p>
Related but separable issue:
For unused bitfields, or other unused fields for that matter,
we should probably say it's the programmer's responsibility
to set them to zero or otherwise ensure they'll be ignored by <code>memcmp</code>.
</p>

<p>
<b>Proposed resolutions:</b>
Using <code>atomic&lt;struct-with-padding&gt;::compare_exchange_strong</code>
should be either:
</p>

<ol>
<li>ill-formed, or</li>
<li>well-defined.</li>
</ol>

<p>
I propose Option 1 for C++0x for expediency,
though I'm not sure how to say it.
I would be happy with Option 2,
which I believe would mean that
<code>compare_exchange_strong</code> would be implemented
to avoid comparing padding bytes,
or something equivalent
such as always zeroing out padding when loading/storing/comparing.
(Either implementation might require compiler support.)
</p>

<p><i>[ Summit: ]</i></p>

<blockquote>
<p>
Move to open. Blocked until concepts for atomics are addressed.
</p>
</blockquote>

<p><i>[ Post Summit Anthony adds: ]</i></p>

<blockquote>
<p>
The resoultion of LWG 923 should resolve this issue as well.
</p>
</blockquote>

<p><b>Proposed resolution:</b></p>

<h3><a name="concept_wording">Wording</a></h3>

<h4><a name="atomics.types.generic_concept">29.5.3 Generic Types [atomic.types.generic]</a></h4>

<p>
Edit paragraph 1 as follows.
</p>

<blockquote>
<p>
There is a generic class template <code>atomic&lt;T&gt;</code>.
The type of the template argument <code>T</code>
shall be <del>trivially copy assignable and bitwise equality comparable</del>
<ins>trivially copyable (3.9 [basic.types])</ins>.
[<i>Note:</i>
Type arguments that are not also statically initializable
<del>and trivially destructable</del>
may be difficult to use.
&mdash;<i>end note</i>]
</p>
</blockquote>

<h4><a name="atomics.types.operations">29.6 Operations on Atomic Types [atomics.types.operations]</a></h4>

<p>
Edit paragraph 18 as follows.
</p>

<blockquote>
<p><i>Effects:</i>
Atomically, compares the <del>value</del> <ins>contents of the memory</ins>
pointed to by <code>object</code> or by <code>this</code>
for equality with that in <code>expected</code>,
and if true, replaces the <del>value</del> <ins>contents of the memory</ins>
pointed to by <code>object</code> or by <code>this</code>
with <ins>that in</ins> <code>desired</code>,
and if false, updates the <del>value</del> <ins>contents of the memory</ins>
in <code>expected</code>
with the <del>value</del> <ins>contents of the memory</ins>
pointed to by <code>object</code> or by <code>this</code>.
Further, if the comparison is true,
memory is affected according to the value of <code>success</code>,
and if the comparison is false,
memory is affected according to the value of <code>failure</code>.
When only one <code>memory_order</code> argument is supplied,
the value of <code>success</code> is <code>order</code>,
and the value of <code>failure</code> is <code>order</code>
except that
a value of <code>memory_order_acq_rel</code>
shall be replaced by the value <code>memory_order_acquire</code>
and a value of <code>memory_order_release</code>
shall be replaced by the value <code>memory_order_relaxed</code>.
These operations are atomic read-modify-write operations (1.10).
</p>
</blockquote>

<p>
Edit paragraph 20 as follows.
</p>

<blockquote>
<p>
[<i>Note:</i> The effect of the compare-and-exchange operations is
</p>
<blockquote><pre><code>
if (<del>*object == *expected</del>
    <ins>memcmp(object,expected,sizeof(*object))==0</ins>)
    <del>*object = desired</del>
    <ins>memcpy(object,&amp;desired,sizeof(*object))</ins>;
else
    <del>*expected = *object</del>
    <ins>memcpy(expected,object,sizeof(*object))</ins>;
</code></pre></blockquote>
<p>
&mdash;<i>end note</i>]
<ins>
[<i>Example:</i>
The expected use of the compare-and-exchange operations is as follows.
The compare-and-exchange operations will update <code>expected</code>
when another iteration of the loop is needed.</ins>
</p>
<blockquote>
<pre><code>
<ins>expected = current.load();
do { desired = function(expected);
} while (!current.compare_exchange(expected, desired));</ins>
</code></pre>
</blockquote>
<p>
<ins>
&mdash;<i>end example</i>]
</ins>
</p>
</blockquote>

<p>
Edit paragraph 21 as follows.
</p>

<blockquote>
<p>
<i>Remark:</i>
The weak compare-and-exchange operations may fail spuriously,
that is, return false while leaving the <del>value</del>
<ins>contents of memory</ins>
pointed to by expected unchanged.
[<i>Note:</i>
This spurious failure enables implementation of compare-and-exchange
on a broader class of machines,
e.g., load-locked store-conditional machines.
<del>&mdash;<i>end note</i>]
[<i>Example:</i></del>
A consequence of spurious failure is that
nearly all uses of weak compare-and-exchange will be in a loop.
</p>
<blockquote>
<pre><code>
<del>expected = current.load();
do desired = function(expected);
while (!current.compare_exchange(expected, desired));</del>
</code></pre>
</blockquote>
<p>
When a compare-and-exchange is in a loop,
the weak version will yield better performance on some platforms.
When a weak compare-and-exchange would require a loop
and a strong one would not, the strong one is preferable.
<del>&mdash;<i>end example</i>]</del>
<ins>&mdash;<i>end note</i>]</ins>
<p>
</blockquote>

<p>
Insert a new paragraph after paragraph 21 as follows.
</p>

<blockquote>
<p><ins>
[<i>Note:</i>
The <code>memcpy</code> and <code>memcmp</code> semantics
of the compare-and-exchange operations
may result in failed comparisons for values
that compare equal with <code>operator==</code>
if the underlying type has padding bits,
has trap values,
or has alternate representations of the same value.
A consequence is that <code>compare_exchange_strong</code>
should be used with extreme care.
On the other hand,
<code>compare_exchange_weak</code>
should converge rapidly.
&mdash;<i>end note</i>]
</ins>
</p>
</blockquote>


<h2><a name="fence">Fences</a></h2>
<h3><a name="fence_issues">Issues</a></h3>

<h4><a name="LWG926">LWG 926: Sequentially consistent fences, relaxed operations and modification order</a></h4>

<p><b>Status:</b> Open</p>

<p><b>Submitter:</b> Anthony Williams</p>

<p><b>Discussion:</b>
There was an interesting issue raised over on comp.programming.threads today
regarding the following example
</p>

<blockquote><pre><code>
// Thread 1:
x.store(1, memory_order_relaxed);           // SX
atomic_thread_fence(memory_order_seq_cst);  // F1
y.store(1, memory_order_relaxed);           // SY1
atomic_thread_fence(memory_order_seq_cst);  // F2
r1 = y.load(memory_order_relaxed);          // RY

// Thread 2:
y.store(0, memory_order_relaxed);          // SY2
atomic_thread_fence(memory_order_seq_cst); // F3
r2 = x.load(memory_order_relaxed);         // RX
</code></pre></blockquote>

<p>
is the outcome <code>r1 == 0</code> and <code>r2 == 0</code> possible?
</p>

<p>
I think the intent is that this is not possible,
but I am not sure the wording guarantees that.
Here is my analysis:
</p>

<p>
Since all the fences are SC, there must be a total order between them.
<code>F1</code> must be before <code>F2</code> in that order
since they are in the same thread.
Therefore <code>F3</code> is either before <code>F1</code>,
between <code>F1</code> and <code>F2</code> or after <code>F2</code>.
</p>

<p>
If <code>F3</code> is <em>after</em> <code>F2</code>,
then we can apply 29.3 [atomics.order]p5 from
<a href="../../papers/2008/n2798.pdf">N2798</a>:
</p>

<blockquote>
<p>
For atomic operations <code>A</code> and <code>B</code>
on an atomic object <code>M</code>,
where <code>A</code> modifies <code>M</code> and <code>B</code> takes its value,
if there are <code>memory_order_seq_cst</code> fences <code>X</code> and <code>Y</code>
such that <code>A</code> is sequenced before <code>X</code>,
<code>Y</code> is sequenced before <code>B</code>,
and <code>X</code> precedes <code>Y</code> in <code>S</code>,
then <code>B</code> observes either
the effects of <code>A</code> or
a later modification of <code>M</code> in its modification order.
</p>
</blockquote>

<p>
In this case, <code>A</code> is <code>SX</code>, <code>B</code> is <code>RX</code>,
the fence <code>X</code> is <code>F2</code> and the fence <code>Y</code> is <code>F3</code>,
so <code>RX</code> must see 1.
</p>

<p>
If <code>F3</code> is <em>before</em> <code>F2</code>,
this doesn't apply,
but <code>F3</code> can therefore be before or after <code>F1</code>.
</p>

<p>
If <code>F3</code> is <em>after</em> <code>F1</code>,
the same logic applies,
but this time the fence <code>X</code> is <code>F1</code>.
Therefore again, <code>RX</code> must see 1.
</p>

<p>
Finally we have the case that
<code>F3</code> is <em>before</em> <code>F1</code> in the SC ordering.
There are now no guarantees about <code>RX</code>,
and <code>RX</code> can see <code>r2==0</code>.
</p>

<p>
We can apply 29.3 [atomics.order]p5 again.
This time,
<code>A</code> is <code>SY2</code>, <code>B</code> is <code>RY</code>,
<code>X</code> is <code>F3</code> and <code>Y</code> is <code>F1</code>.
Thus <code>RY</code> must observe the effects of <code>SY2</code>
or a later modification of <code>y</code> in its modification order.
</p>

<p>
Since <code>SY1</code> is sequenced before <code>RY</code>,
<code>RY</code> must observe the effects of <code>SY1</code>
or a later modification of <code>y</code> in its modification order.
</p>

<p>
In order to ensure that <code>RY</code> sees <code>(r1==1)</code>,
we must see that <code>SY1</code> is later in the modification order of <code>y</code>
than <code>SY2</code>.
</p>

<p>
We're now skating on thin ice.
Conceptually, <code>SY2</code> happens-before <code>F3</code>,
<code>F3</code> is SC-ordered before <code>F1</code>,
<code>F1</code> happens-before <code>SY1</code>,
so <code>SY1</code> is later in the modification order <code>M</code> of <code>y</code>,
and <code>RY</code> must see the result of <code>SY1</code> (<code>r1==1</code>).
However, I don't think the words are clear on that.
</p>

<p><i>[ Post Summit Hans adds: ]</i></p>

<blockquote>
<p>
In my (Hans') view,
our definition of fences will always be weaker
than what particular hardware will guarantee.
<code>Memory_order_seq_cst</code> fences
inherently don't guarantee sequential consistency anyway,
for good reasons (e.g. because they can't enforce a total order on stores).
Hence I don't think the issue demonstrates
a gross failure to achieve what we intended to achieve.
The example in question is a bit esoteric.
Hence, in my view,
living with the status quo certainly wouldn't be a disaster either.
</p>

<p>
In any case, we should probably add text along the lines of the following
between p5 and p6 in 29.3 [atomics.order]:
</p>

<blockquote>
<p>
[<i>Note:</i>
<code>Memory_order_seq_cst</code> only ensures sequential consistency
for a data-race-free program
that uses exclusively <code>memory_order_seq_cst</code> operations.
Any use of weaker ordering will invalidate this guarantee
unless extreme care is used.
In particular, <code>memory_order_seq_cst</code> fences
only ensure a total order for the fences themselves.
They cannot, in general,
be used to restore sequential consistency
for atomic operations with weaker ordering specifications.
&mdash;<i>end note</i>]
</p>
</blockquote>

<p>
Also see thread beginning at c++std-lib-23271.
</p>

</blockquote>

<p><i>[ Herve's correction: ]</i></p>

<blockquote>
<p>
Minor point, and sorry for the knee jerk reaction:
I admit to having no knowledge of Memory_order_seq_cst,
but my former boss (John Lakos)
has ingrained an automatic introspection on the use of "only".
I think you meant:
</p>

<blockquote>
<p>
[Note: <code>Memory_order_seq_cst</code> ensures sequential consistency
only for . . . .
In particular,
<code>memory_order_seq_cst</code> fences ensure a total order only for . . .
</p>
</blockquote>

<p>
Unless, of course,
<code>Memory_order_seq_cst</code> really do nothing
but ensure sequential consistency for a data-race-free program
that uses exclusively <code>memory_order_seq_cst</code> operations.
</p>
</blockquote>

<p><b>Proposed resolution:</b>
Add a new paragraph after 29.3 [atomics.order]p5 that says
</p>

<blockquote>
<p>
For atomic operations <code>A</code> and <code>B</code> on an atomic object <code>M</code>,
where <code>A</code> and <code>B</code> modify <code>M</code>,
if there are <code>memory_order_seq_cst</code> fences <code>X</code> and <code>Y</code>
such that <code>A</code> is sequenced before <code>X</code>,
<code>Y</code> is sequenced before <code>B</code>,
and <code>X</code> precedes <code>Y</code> in <code>S</code>,
then <code>B</code> occurs later than <code>A</code>
in the modifiction order of <code>M</code>.
</p>
</blockquote>

<h4><a name="UK313">UK 313: seq_cst Fences</a></h4>

<p><b>Comment:</b>
seq_cst fences don't necessarily guarantee ordering.
</p>

<p><b>Suggestion:</b>
Add a new paragraph after 29.1 [atomics.order] p5 that says
"For atomic operations A and B on an atomic object M, where A and B modify M,
if there are memory_order_seq_cst fences X and Y such that
A is sequenced before X, Y is sequenced before B, and X precedes Y in S,
then B occurs later than A in the modifiction order of M."
</p>

<p><b>Disposition:</b>
</p>

<p><b>Committee:</b>
</p>

<h3><a name="fence_wording">Wording</a></h3>

<h4><a name="atomics.order">29.3 Order and Consistency [atomics.order]</a></h4>

<p>
Add a new paragraph after paragraph 5 as follows.
</p>

<blockquote>
<p>
<ins>For atomic operations <code>A</code> and <code>B</code>
on an atomic object <code>M</code>,
where <code>A</code> and <code>B</code> modify <code>M</code>,
if there are <code>memory_order_seq_cst</code> fences
<code>X</code> and <code>Y</code>
such that <code>A</code> is sequenced before <code>X</code>,
<code>Y</code> is sequenced before <code>B</code>,
and <code>X</code> precedes <code>Y</code> in <code>S</code>,
then <code>B</code> occurs later than <code>A</code>
in the modifiction order of <code>M</code>.</ins>
</p>
</blockquote>

<p>
Add a new paragraph after the above paragraph as follows.
</p>

<blockquote>
<p>
<ins>[<i>Note:</i>
<code>Memory_order_seq_cst</code> ensures sequential consistency
only for a data-race-free program
that uses exclusively <code>memory_order_seq_cst</code> operations.
Any use of weaker ordering will invalidate this guarantee
unless extreme care is used.
In particular, <code>memory_order_seq_cst</code> fences
ensure a total order only for the fences themselves.
They cannot, in general,
be used to restore sequential consistency
for atomic operations with weaker ordering specifications.
&mdash;<i>end note</i>]</ins>
</p>
</blockquote>

<h2><a name="lockfree">Lock Free</a></h2>
<h3><a name="lockfree_issues">Issues</a></h3>

<h4><a name="1146">LWG 1146, US 88: "lockfree" does not say enough</a></h4>

<p><b>Status:</b> New</p>

<p><b>Submitter:</b> Jeffrey Yasskin</p>

<p><b>Discussion:</b>
The "lockfree" facilities do not tell the programmer enough.
</p>

<p>
There are 2 problems here.
First, at least on x86,
it's less important to me whether some integral types are lock free
than what is the largest type I can pass to atomic and have it be lock-free.
For example, if <code>long long</code>s are not lock-free,
<code>ATOMIC_INTEGRAL_LOCK_FREE</code> is probably 1,
but I'd still be interested in knowing whether longs are always lock-free.
Or if long longs at any address are lock-free,
I'd expect <code>ATOMIC_INTEGRAL_LOCK_FREE</code> to be 2,
but I may actually care whether I have access to
the <code>cmpxchg16b</code> instruction.
None of the support here helps with that question.
(There are really 2 related questions here:
what alignment requirements are there for lock-free access;
and what processor is the program actually running on,
as opposed to what it was compiled for?)
</p>

<p>
Second, having <code>atomic_is_lock_free</code> only apply to individual objects
is pretty useless
(except, as Lawrence Crowl points out,
for throwing an exception when an object is unexpectedly not lock-free).
I'm likely to want to use its result to decide what algorithm to use,
and that algorithm is probably going to allocate new memory
containing atomic objects and then try to act on them.
If I can't predict the lock-freedom of the new object
by checking the lock-freedom of an existing object,
I may discover after starting the algorithm that I can't continue.
</p>

<p><i>[
2009-06-16 Jeffrey Yasskin adds:
]</i></p>

<blockquote>
<p>
To solve the first problem, I think 2 macros would help:
<code>MAX_POSSIBLE_LOCK_FREE_SIZE</code> and
<code>MAX_GUARANTEED_LOCK_FREE_SIZE</code>,
which expand to the maximum value of <code>sizeof(T)</code>
for which atomic may (or will, respectively) use lock-free operations.
Lawrence points out that this
"relies heavily on implementations
using word-size compare-swap on sub-word-size types,
which in turn requires address modulation."
He expects that to be the end state anyway, so it doesn't bother him much.
</p>

<p>
To solve the second,
I think one could specify that equally aligned objects of the same type
will return the same value from <code>atomic_is_lock_free()</code>.
I don't know how to specify "equal alignment".
Lawrence suggests an additional function,
<code>atomic_is_always_lock_free()</code>.
</p>
</blockquote>

<p><b>Committee:</b>
</p>

<ul>
<li>Will expand ATOMIC_INTEGRAL_LOCK_FREE
to add a macro for each integer size &mdash;
one for char/schar/uchar, one for short/ushort, etc.</li>
<li>Will require that atomic types are aligned to necessary alignment
to make them lock-free if possible</li>
<li>Will make is_lock_free apply to all instances of a given type,
allowing a null pointer to be passed to the namespace-level function</li>
<li>Relatedly, Mike Sperts will create an issue
to propose adding a traits mechanism to check the compile-time properties
through a template mechanism rather than macros</li>
</ul>

<h3><a name="lockfree_wording">Wording</a></h3>

<h4><a name="atomics.lockfree">29.4 Lock-free Property [atomics.lockfree]</a></h4>

<p>
Edit the synopsis as follows.
</p>

<blockquote><pre><code>
<del>namespace std {</del>
<del>#define ATOMIC_INTEGRAL_LOCK_FREE <var>unspecified</var></del>
<ins>#define ATOMIC_CHAR_LOCK_FREE <var>unspecified</var></ins>
<ins>#define ATOMIC_CHAR16_T_LOCK_FREE <var>unspecified</var></ins>
<ins>#define ATOMIC_CHAR32_T_LOCK_FREE <var>unspecified</var></ins>
<ins>#define ATOMIC_WCHAR_T_LOCK_FREE <var>unspecified</var></ins>
<ins>#define ATOMIC_SHORT_LOCK_FREE <var>unspecified</var></ins>
<ins>#define ATOMIC_INT_LOCK_FREE <var>unspecified</var></ins>
<ins>#define ATOMIC_LONG_LOCK_FREE <var>unspecified</var></ins>
<ins>#define ATOMIC_LLONG_LOCK_FREE <var>unspecified</var></ins>
#define ATOMIC_ADDRESS_LOCK_FREE <var>unspecified</var>
<del>}</del>
</code></pre></blockquote>

<p>
Edit paragraph 1 as follows.
<p>

<blockquote>
<p>
The <ins><code>ATOMIC_...._LOCK_FREE</code></ins> macros
<del><code>ATOMIC_INTEGRAL_LOCK_FREE and ATOMIC_ADDRESS_LOCK_FREE</code></del>
indicate the <del>general</del> lock-free property
of <del>integral and address</del> <ins>the corresponding</ins>
atomic types<ins>,
with the signed and unsigned variants grouped together</ins>.
The properties also apply
to the corresponding specializations of the atomic template.
A value of 0 indicates that the types are never lock-free.
A value of 1 indicates that the types are sometimes lock-free.
A value of 2 indicates that the types are always lock-free.
</p>
</blockquote>

<p>
Edit paragraph 2 as follows.
<p>

<blockquote>
<p>
The function <code>atomic_is_lock_free</code> (29.6)
indicates whether the <del>object</del> <ins>type</ins> is lock-free.
<del>The result of a lock-free query on one object
cannot be inferred from
the result of a lock-free query on another object.</del>
<ins>In any given program execution,
the result of the lock-free query
shall be consistent for all pointers of the same type.</ins>
</p>
</blockquote>

<h2><a name="typedef">Typedefs</a></h2>
<h3><a name="typedef_issues">Issues</a></h3>

<h4><a name="937">LWG 937, US 89</a></h4>

<p><b>Comment:</b>
The types in the table "Atomics for standard typedef types"
should be typedefs, not classes.
These semantics are necessary for compatibility with C.
</p>

<p><b>Suggestion:</b>
Change the classes to typedefs.
</p>

<p><b>Committee:</b>
Direct the editor to turn the types into typedefs
as proposed in the comment.
Paper approved by committee used typedefs,
this appears to have been introduced as an editorial change.
Rationale: for compatibility with C.
</p>

<h4><a name="LWG943">LWG 943: <code>ssize_t</code> undefined</a></h4>

<p>
<b>Status:</b> Tentatively Ready
<b>Submitter:</b> Holger Grund <b>Opened:</b> 2008-12-19  <b>Last modified:</b> 2009-05-23</p>
<p><b>View all issues with</b> <a href="lwg-status.html#Tentatively Ready">Tentatively Ready</a> status.</p>

<p><b>Discussion:</b></p>
<p>
There is a row in "Table 122 - Atomics for standard typedef types"
in 29.5.1 [atomics.types.integral] with <code>atomic_ssize_t</code>
and <code>ssize_t</code>. Unless, I'm missing something <code>ssize_t</code>
is not defined by the standard.
</p>

<p><i>[
Summit:
]</i></p>

<blockquote>
<p>
Move to review.
Proposed resolution: Remove the typedef.
Note: <code>ssize_t</code> is a POSIX type.
</p>
</blockquote>

<p><i>[
Batavia (2009-05):
]</i></p>

<blockquote>
<p>
We agree with the proposed resolution.
Move to Tentatively Ready.
</p>
</blockquote>


<p><b>Proposed resolution:</b></p>
<p>
Remove the row containing <code>ssize_t</code> from Table 119
"Atomics for standard typedef types" in 29.5.2 [atomics.types.address].
</p>


<h3><a name="typedef_wording">Wording</a></h3>

<h4><a name="atomics.types.integral_typedef">29.5.1 Integral Types [atomics.types.integral]</a></h4>

<p>
Edit paragraph 1 as follows.
</p>

<blockquote>
<p>
The name <code>atomic_<var>itype</var></code>
and the functions operating on it
in the preceding synopsis
are placeholders for a set of classes and functions.
Throughout the preceding synopsis,
<code>atomic_<var>itype</var></code> should be replaced by
each of the class names in table 119 <del>and table 120,</del> and
integral should be replaced by the integral type
corresponding to the class name.
<ins>Table 120 shows typedefs to atomic integral classes
and the corresponding <code>&lt;stdint.h&gt;</code> typedefs.</ins>
</p>
</blockquote>

<p>
In table 119, 
remove the row containing <code>ssize_t</code>.
</p>

<p>
Edit the heading in table 120 as follows.
</p>

<blockquote>
<p>
<del>Class name</del> <ins>atomic typedef name</ins>
<del>Integral type</del> <ins>stdint typedef name</ins>
</p>
</blockquote>

<h2><a name="volatile">Volatile</a></h2>
<h3><a name="volatile_issues">Issues</a></h3>

<h4><a name="LWG1147">LWG 1147, US 90: non-volatile atomic functions</a></h4>

<p><b>Status:</b> New</p>

<p><b>Submitter:</b> Jeffrey Yasskin</p>

<p><b>Discussion</b>
The C++0X draft
declares all of the functions dealing with atomics
(section 29.6 [atomics.types.operations])
to take volatile arguments.
Yet it also says (29.4-3),
</p>

<blockquote>
<p>
[<i>Note:</i>
Many operations are volatile-qualified.
The "volatile as device register" semantics have not changed in the standard.
This qualification means that volatility is preserved
when applying these operations to volatile objects.
It does not mean that operations on non-volatile objects become volatile.
Thus, volatile qualified operations on non-volatile objects
may be merged under some conditions. &mdash;end note ]
</p>
</blockquote>

<p>
I was thinking about how to implement this in gcc,
and I believe that we'll want to overload most of the functions
on volatile and non-volatile.
Here's why:
</p>

<p>
To let the compiler take advantage of the permission
to merge non-volatile atomic operations and reorder atomics in certain,
we'll need to tell the compiler backend
about exactly which atomic operation was used.
So I expect most of the functions of the form atomic_&lt;op&gt;_explicit()
(e.g. atomic_load_explicit, atomic_exchange_explicit,
atomic_fetch_add_explicit, etc.)
to become compiler builtins.
A builtin can tell whether its argument was volatile or not,
so those functions don't really need extra explicit overloads.
However, I don't expect that we'll want to add builtins
for every function in chapter 29,
since most can be implemented in terms of the _explicit free functions:
</p>

<pre><code>
class atomic_int {
  __atomic_int_storage value;
 public:
  int fetch_add(int increment, memory_order order = memory_order_seq_cst) volatile {
    // &amp;value has type "volatile __atomic_int_storage*".
    atomic_fetch_add_explicit(&amp;value, increment, order);
  }
  ...
};
</code></pre>

<p>
But now this <em>always</em> calls
the volatile builtin version of atomic_fetch_add_explicit(),
even if the atomic_int wasn't declared volatile.
To preserve volatility and the compiler's permission to optimize,
I'd need to write:

</p>

<pre><code>
class atomic_int {
  __atomic_int_storage value;
 public:
  int fetch_add(int increment, memory_order order = memory_order_seq_cst) volatile {
    atomic_fetch_add_explicit(&amp;value, increment, order);
  }
  int fetch_add(int increment, memory_order order = memory_order_seq_cst) {
    atomic_fetch_add_explicit(&amp;value, increment, order);
  }
  ...
};
</code></pre>

<p>
But this is visibly different from the declarations in the standard
because it's now overloaded.
(Consider passing &amp;atomic_int::fetch_add as a template parameter.)
</p>

<p>
The implementation may already have permission to add overloads
to the member functions:
</p>

<blockquote>

<p>
17.6.4.5 [member.functions]
An implementation may declare
additional non-virtual member function signatures within a class:<br>
...
</p>
<ul>
<li>by adding a member function signature for a member function name.</li>
</ul>
</blockquote>

<p>
but I don't see an equivalent permission to add overloads to the free functions.
</p>

<p><i>[
2009-06-16 Lawrence adds:
]</i></p>

<blockquote>
<p>
I recommend allowing non-volatile overloads.
</p>
</blockquote>

<p><b>Committee:</b>
Should explicitly consider the process shared issue. 
908: Move to open. Assign to Lawrence. Related to US 90 comment. 
</p>

<ul>
<li>C committee does not want to make promises about optimizations</li>
<li>Current note in paragraph 3 of [atomics.types.operations]
is based on a wrong assumption</li>
<li>C++ resolution: add the non-volatile overloads.</li>
<li>Expectation that the C standard will be phrased in such a way that
non-volatile atomics are not necessarily forced to be volatile,
even if the standard only specifies the volatile forms</li>
<li>Related issue: process-shared atomics.
More work needs to be done, at a minimum POSIX will need to specify this.</li>
</ul>

<h4><a name="LWG908">LWG 908: Deleted assignment operators for atomic types must be volatile</a></h4>

<p><b>Status:</b> Open</p>

<p><b>Submitter:</b> Anthony Williams</p>

<p>
The deleted copy-assignment operators for the atomic types
are not marked as volatile in N2723,
whereas the assignment operators from the associated non-atomic types are.
e.g.
</p>
<blockquote><pre><code>
atomic_bool&amp; operator=(atomic_bool const&amp;) = delete;
atomic_bool&amp; operator=(bool) volatile;
</code></pre></blockquote>

<p>
This leads to ambiguity when assigning a non-atomic value to a
non-volatile instance of an atomic type:
</p>
<blockquote><pre><code>
atomic_bool b;
b=false;
</code></pre></blockquote>

<p>
Both assignment operators require a standard conversions:
the copy-assignment operator
can use the implicit <code>atomic_bool(bool)</code> conversion constructor
to convert <code>false</code> to an instance of <code>atomic_bool</code>,
or <code>b</code> can undergo a qualification conversion
in order to use the assignment from a plain <code>bool</code>.
</p>

<p>
This is only a problem once issue <a href="lwg-defects.html#845">845</a>
is applied.
</p>

<p><i>[
Summit:
]</i></p>

<blockquote>
<p>
Move to open. Assign to Lawrence. Related to US 90 comment.
</p>
</blockquote>


<p><b>Proposed resolution:</b></p>
<p>
Add volatile qualification to the deleted copy-assignment operator
of all the atomic types:
</p>

<blockquote><pre><code>
atomic_bool&amp; operator=(atomic_bool const&amp;) <ins>volatile</ins> = delete;
atomic_itype&amp; operator=(atomic_itype const&amp;) <ins>volatile</ins> = delete;
</code></pre></blockquote>

<p>
etc.
</p>

<p>
This will mean that the deleted copy-assignment operator
will require <i>two</i> conversions in the above example,
and thus be a worse match than the assignment from plain <code>bool</code>.
</p>

<h3><a name="volatile_wording">Wording</a></h3>

<h4><a name="atomics">29 Atomic operations library [atomics]</a></h4>

<p>
For each volatile qualified function
or function with volatile qualified parameter,
add a non-volatile qualified version.
For each version of the assignment operator,
add a volatile qualified version.
</p>

<h2><a name="memcmpxchg">Memory Order of Compare Exchange</a></h2>
<h3><a name="memcmpxchg_issues">Issues</a></h3>

<h4><a name="US91">US 91: Failed Compare Exchange</a></h4>

<p><b>Comment:</b>
Whether or not a failed compare_exchange is a RMW operation
(as used in 1.10 [intro.multithread]) is unclear.
</p>

<p><b>Suggestion:</b>
Make failing compare_exchange operations not be RMW.
See the attached paper under "atomic RMW status of failed compare_exchange".
</p>

<p><b>Disposition:</b>
Accepted.
</p>

<p><b>Committee:</b>
</p>

<h4><a name="LWG1043"></a>LWG 1043: Response to US 91</h4>

<p><b>Status:</b> Review</p>

<p><b>Submitter:</b> Alisdair Meredith</p>

<p>
It is unclear whether or not a failed <code>compare_exchange</code> is a RMW operation
(as used in 1.10 [intro.multithread]).
</p>

<p>
Suggested solution:
</p>

<p>
Make failing <code>compare_exchange</code> operations <b>not</b> be RMW.
</p>

<p><i>[
Anthony Williams adds:
]</i></p>


<blockquote>
<p>
In 29.6 [atomics.types.operations] p18 it says that
"These operations are atomic read-modify-write operations" (final sentence).
This is overly restrictive on the implementations of
<code>compare_exchange_weak</code> and <code>compare_exchange_strong</code>
on platforms without a native CAS instruction.
</p>
</blockquote>

<p><i>[
Summit:
]</i></p>

<blockquote>
<p>
Group agrees with the resolution as proposed by Anthony Williams
in the attached note.
</p>
</blockquote>

<p><i>[
Batavia (2009-05):
]</i></p>

<blockquote>
<p>
We recommend the proposed resolution be reviewed
by members of the Concurrency Subgroup.
</p>
</blockquote>

<p><b>Proposed resolution:</b></p>
<p>
Change 29.6 [atomics.types.operations] p18:
</p>

<blockquote>
<p>
-18- <i>Effects:</i> Atomically, compares the value pointed to by
<code>object</code> or by <code>this</code> for equality with that in
<code>expected</code>, and if true, replaces the value pointed to by
<code>object</code> or by <code>this</code> with desired, and if false, updates
the value in <code>expected</code> with the value pointed to by
<code>object</code> or by <code>this</code>. Further, if the comparison is true,
memory is affected according to the value of <code>success</code>, and if the
comparison is false, memory is affected according to the value of
<code>failure</code>. When only one <code>memory_order</code> argument is
supplied, the value of <code>success</code> is <code>order</code>, and the value
of <code>failure</code> is <code>order</code> except that a value of
<code>memory_order_acq_rel</code> shall be replaced by the value
<code>memory_order_acquire</code> and a value of
<code>memory_order_release</code> shall be replaced by the value
<code>memory_order_relaxed</code>. <ins>If the comparison is <code>true</code>, </ins>
<del>T</del><ins>t</ins>hese operations are atomic
read-modify-write operations (1.10). 
<ins>If the comparison is <code>false</code>, these
operations are atomic load operations.</ins>
</p>
</blockquote>

<h4><a name="US92">US 92: RMW with Consume</a></h4>

<p><b>Comment:</b>
The effect of memory_order_consume with atomic RMW operations is unclear.
</p>

<p><b>Suggestion:</b>
Follow the lead of fences [atomics.fences],
and promote memory_order_consume to memory_order_acquire with RMW operations.   
</p>

<p><b>Disposition:</b>
NAD. We can not see the issue being suggested by the comment.
</p>

<p><b>Committee:</b>
</p>

<h3><a name="memcmpxchg_wording">Wording</a></h3>

<h4><a name="atomics.types.operations">29.6 Operations on Atomic Types [atomics.types.operations]</a></h4>

<p>
Edit paragraph 18 as follows.
</p>

<blockquote>
<p><i>Effects:</i>
Atomically, compares the value pointed to by <code>object</code>
or by <code>this</code> for equality with that in <code>expected</code>,
and if true,
replaces the value pointed to by <code>object</code> or by <code>this</code>
with desired,
and if false,
updates the value in <code>expected</code>
with the value pointed to by <code>object</code>
or by <code>this</code>.
Further, if the comparison is true,
memory is affected according to the value of <code>success</code>,
and if the comparison is false,
memory is affected according to the value of <code>failure</code>.
When only one <code>memory_order</code> argument is supplied,
the value of <code>success</code> is <code>order</code>,
and the value of <code>failure</code> is <code>order</code> except that
a value of <code>memory_order_acq_rel</code>
shall be replaced by the value <code>memory_order_acquire</code>
and a value of <code>memory_order_release</code>
shall be replaced by the value <code>memory_order_relaxed</code>.
<ins>If the comparison is <code>true</code>, </ins>
<del>These</del> <ins>these</ins> operations
are atomic read-modify-write operations (1.10). 
<ins>If the comparison is <code>false</code>,
these operations are atomic load operations.</ins>
</p>
</blockquote>

<h2><a name="flag">Atomic Flag</a></h2>
<h3><a name="flag_issues">Issues</a></h3>

<h4><a name="WG14">LWG ?, WG14: Flag Initialization</a></h4>

<p><b>Comment:</b>
</p>

<p><b>Suggestion:</b>
</p>

<p><b>Disposition:</b>
</p>

<p><b>Committee:</b>
</p>

<ul>
<li>C committee believes atomic_flag's initialization
should be indeterminate</li>
<li>C++ will add atomic_flag initialized to be indeterminate</li>
<li>May not be necessary to add any language to clear to specify that
calling it will not cause undefined behaviour if the atomic_flag
is indeterminate, but if necessary, will be added</li>
<li>Clark notes there is no paper trail (e.g. an NB comment)
justifying this change.
Requires a liaison statement from the C committee.
Expect this will happen.</li>
</ul>

<h3><a name="flag_wording">Wording</a></h3>

<h4><a name="atomics.flag">29.7 Flag Type and Operations [atomics.flag]</a></h4>

<p>
Edit paragraph 4 as follows.
</p>

<blockquote>
<p>
The macro <code>ATOMIC_FLAG_INIT</code>
shall be defined in such a way that it can be used to
initialize an object of type <code>atomic_flag</code> to the clear state.
For a static-duration object, that initialization shall be static.
<del>A program that uses an object of type <code>atomic_flag</code>
without initializing it with the macro <code>ATOMIC_FLAG_INIT</code>
is ill-formed.</del>
<ins>An uninitialized <code>atomic_flag</code>
shall indeterminately have an initial state of either set or clear.</ins>
[<i>Example:</i>
</p>
<blockquote>
<pre><code>
atomic_flag guard = ATOMIC_FLAG_INIT;
</code></pre>
</blockquote>
<p>
&mdash;<i>end example</i>]
</p>
</blockquote>

<h2><a name="derivation">Derivation</a></h2>
<h3><a name="derivation_issues">Issues</a></h3>

<h4><a name="LWG944"></a>LWG 944: <code>atomic&lt;bool&gt;</code> derive from <code>atomic_bool</code>?</h4>

<p><b>Status:</b> Open</p>

<p><b>Submitter:</b> Holger Grund</p>

<p><b>Discussion:</b>
I think it's fairly obvious that
<code>atomic&lt;bool&gt;</code>
is supposed to be derived from <code>atomic_bool</code>
(and otherwise follow the <code>atomic&lt;integral&gt;</code> interface),
though I think the current wording doesn't support this.
I raised this point along with <code>atomic&lt;floating-point&gt;</code>
privately with Herb
and I seem to recall it came up in the resulting discussion on this list.
However,
I don't see anything on the current libs issue list mentioning this problem.
</p>

<p>
29.5.3 [atomics.types.generic]/3 reads
</p>

<blockquote>
<p>
There are full specializations over the integral types
on the atomic class template.
For each integral type integral in the second column of table 121 or table 122,
the specialization <code>atomic&lt;integral&gt;</code>
shall be publicly derived from
the corresponding atomic integral type in the first column of the table.
These specializations shall have
trivial default constructors and trivial destructors.
</p>
</blockquote>

<p>
Table 121 does not include (<code>atomic_bool</code>, <code>bool</code>),
so that this should probably be mentioned explicitly in the quoted paragraph.
</p>

<p><i>[
Summit:
]</i></p>

<blockquote>
<p>
Move to open. Lawrence will draft a proposed resolution.
Also, ask Howard to fix the title.
</p>
</blockquote>

<p><i>[
Post Summit Anthony provided proposed wording.
]</i></p>

<p><b>Proposed resolution:</b></p>

<p>
Replace paragraph 3 in 29.5.3 [atomics.types.generic] with
</p>

<blockquote>
<p>
-3- There are full specializations over the integral types
on the <code>atomic</code> class template.
For each integral type <code>integral</code>
in the second column of table 121 or table 122,
the specialization <code>atomic&lt;integral&gt;</code>
shall be publicly derived from
the corresponding atomic integral type in the first column of the table.
<ins>In addition, the specialization <code>atomic&lt;bool&gt;</code>
shall be publicly derived from <code>atomic_bool</code>.</ins>
These specializations shall have trivial default
constructors and trivial destructors.
</p>
</blockquote>

<p><b>Committee:</b>
Move to open.
Lawrence will draft a proposed resolution.
Also, ask Howard to fix the title.
</p>

<h3><a name="derivation_wording">Wording</a></h3>

<h4><a name="atomics.types.generic_derivation">29.5.3 Generic Types [atomic.types.generic]</a></h4>

<p>
Edit paragraph 3 as follows.
</p>

<blockquote>
<p>
There are full specializations over the integral types
on the <code>atomic</code> class template.
For each integral type <code>integral</code>
in the second column of table 118 or table 119,
the specialization <code>atomic&lt;integral&gt;</code>
shall be publicly derived from
the corresponding atomic integral type in the first column of the table.
These specializations
shall have trivial default constructors and trivial destructors.
<ins>In addition, the specialization <code>atomic&lt;bool&gt;</code>
shall be publicly derived from <code>atomic_bool</code>.</ins>
These specializations shall have trivial default
constructors and trivial destructors.
</p>
</blockquote>

<h2><a name="const">Const Load</a></h2>
<h3><a name="const_issues">Issues</a></h3>

<h4><a name="LWG879">LWG 879: Atomic load const qualification</a></h4>

<p><b>Status:</b> Review</p>

<p><b>Submitter:</b> Alexander Chemeris</p>

<p><b>Discussion:</b>
The <code>atomic_address</code> type
and <code>atomic&lt;T*&gt;</code> specialization
provide atomic updates to pointers.
However, the current specification requires that
the types pointer be to non-const objects.
This restriction is unnecessary and unintended.
</p>

<p><b>Proposed resolution:</b>
Add const qualification to the pointer values of
the <code>atomic_address</code> and <code>atomic&lt;T*&gt;</code>
specializations.
E.g.
</p>

<blockquote><pre><code>
typedef struct atomic_address {
   void store(<ins>const</ins> void*, memory_order = memory_order_seq_cst) volatile;
   void* exchange( <ins>const</ins> void*, memory_order = memory_order_seq_cst) volatile;
   bool compare_exchange( <ins>const</ins> void*&amp;, <ins>const</ins> void*,
                          memory_order, memory_order) volatile;
   bool compare_exchange( <ins>const</ins> void*&amp;, <ins>const</ins> void*,
                          memory_order = memory_order_seq_cst ) volatile;
   void* operator=(<ins>const</ins> void*) volatile;
} atomic_address;

void atomic_store(volatile atomic_address*, <ins>const</ins> void*);
void atomic_store_explicit(volatile atomic_address*, <ins>const</ins> void*,
                          memory_order);
void* atomic_exchange(volatile atomic_address*<ins>, const void*</ins>);
void* atomic_exchange_explicit(volatile atomic_address*, <ins>const</ins> void*,
                              memory_order);
bool atomic_compare_exchange(volatile atomic_address*,
                            <ins>const</ins> void**, <ins>const</ins> void*);
bool atomic_compare_exchange_explicit(volatile atomic_address*,
                                     <ins>const</ins> void**, <ins>const</ins> void*,
                                     memory_order, memory_order);
</code></pre></blockquote>

<p><b>Committee:</b>
Move to review.
Lawrence will first check with Peter
whether the current examples are sufficient,
or whether they need to be expanded to include all cases. 
</p>

<p><b>Peter:</b>
I think that compare_exchange needs both void*&amp; and const void*&amp;,
and both void** and const void**.
</p>

<pre><code>
struct atomic_address
{
  bool compare_exchange( const void*&amp; , const void* );
};

bool atomic_compare_exchange( volatile atomic_address*,
  const void**, const void* );

int main()
{
  atomic_address x;
  void * p;

  x.compare_exchange( p, 0 ); // error
  atomic_compare_exchange( &amp;x, &amp;p, 0 ); // error
}
</code></pre>

<h3><a name="const_wording">Wording</a></h3>

<h4><a name="atomics.types.address">29.5.2 Address Type [atomic.types.address]</a></h4>

<p>
Edit signatures as follows.
</p>

<blockquote>
<pre><code>
typedef struct atomic_address {
    void store(<ins>const</ins> void*, memory_order = memory_order_seq_cst) volatile;
    void* exchange( <ins>const</ins> void*, memory_order = memory_order_seq_cst) volatile;
    bool compare_exchange_weak( void*&amp;, void*,
                                memory_order, memory_order) volatile;
    bool compare_exchange_strong( void*&amp;, void*,
                                  memory_order, memory_order) volatile;
    bool compare_exchange_weak( void*&amp;, void*,
                                memory_order = memory_order_seq_cst ) volatile;
    bool compare_exchange_strong( void*&amp;, void*,
                                  memory_order = memory_order_seq_cst ) volatile;
    <ins>bool compare_exchange_weak( const void*&amp;, const void*,
                                memory_order, memory_order) volatile;
    bool compare_exchange_strong( const void*&amp;, const void*,
                                  memory_order, memory_order) volatile;
    bool compare_exchange_weak( const void*&amp;, const void*,
                                memory_order = memory_order_seq_cst ) volatile;
    bool compare_exchange_strong( const void*&amp;, const void*,
                                  memory_order = memory_order_seq_cst ) volatile;</ins>
    void* operator=(<ins>const</ins> void*) volatile;
} atomic_address;
</code></pre>
</blockquote>

<h2><a name="parameter">Atomic Exchange Parameter</a></h2>
<h3><a name="parameter_issues">Issues</a></h3>

<h4><a name="880">LWG 880: Missing atomic exchange parameter</a></h4>

<p><b>Status:</b> Open
</p>

<p><b>Submitter:</b> Lawrence Crowl
</p>

<p><b>Discussion:</b>
The <code>atomic_exchange</code> and <code>atomic_exchange_explicit</code> functions
seem to be inconsistently missing parameters.
</p>

<p><b>Proposed resolution:</b></p>

<p>
Add the appropriate parameters.  For example,
</p>

<blockquote><pre><code>
bool atomic_exchange(volatile atomic_bool*<ins>, bool</ins>);
bool atomic_exchange_explicit(volatile atomic_bool*, bool<ins>, memory_order</ins>);
</code></pre></blockquote>

<p><b>Resolution:</b></p>
<p>
Lawrence: Need to write up a list for Pete with details.
</p>

<h3><a name="parameter_wording">Wording</a></h3>

<h4><a name="atomics.syn">29.2 Header <code>&lt;cstdatomic&gt;</code> synopsis [atomic.syn]</a></h4>

<p>
Edit within the synopsis as follows.
</p>

<blockquote>
<p>
....<br>
<code>bool atomic_exchange(volatile atomic_bool*<ins>, bool</ins>);</code><br>
<code>bool atomic_exchange_explicit(volatile atomic_bool*, bool<ins>, memory_order</ins>);</code><br>
....<br>
<var>integral</var> <code>atomic_exchange(volatile atomic_</code><var>itype</var><code>*</code><ins><code>,</code> <var>integral</var></ins><code>);</code><br>
<var>integral</var> <code>atomic_exchange_explicit(volatile atomic_</code><var>itype</var><code>*,</code> <var>integral</var><ins><code>, memory_order</code></ins><code>);</code><br>
....<br>
<code>void* atomic_exchange(volatile atomic_address*<ins>, void*</ins>);</code><br>
<code>void* atomic_exchange_explicit(volatile atomic_address*, void*, memory_order);</code><br>
....<br>
</p>
</blockquote>

<h4><a name="atomics.types.integral_parameter">29.5.1 Integral Types [atomics.types.integral]</a></h4>

<p>
Edit within the synopsis as follows.
</p>

<blockquote>
<p>
....<br>
<code>bool atomic_exchange(volatile atomic_bool*<ins>, bool</ins>);</code><br>
<code>bool atomic_exchange_explicit(volatile atomic_bool*, bool<ins>, memory_order</ins>);</code><br>
....<br>
<var>integral</var> <code>atomic_exchange(volatile atomic_</code><var>itype</var><code>*,</code> <var>integral</var><code>);</code><br>
<var>integral</var> <code>atomic_exchange_explicit(volatile atomic_</code><var>itype</var><code>*,</code> <var>integral</var><code>, memory_order</code><code>);</code><br>
....<br>
</p>
</blockquote>

<h4><a name="atomics.types.address_parameter">29.5.2 Address Type [atomics.types.address]</a></h4>

<p>
Edit within the synopsis as follows.
</p>

<blockquote>
<p>
....<br>
<code>void* atomic_exchange(volatile atomic_address*<ins>, void*</ins>);</code><br>
<code>void* atomic_exchange_explicit(volatile atomic_address*, void*, memory_order);</code><br>
....<br>
</p>
</blockquote>

</body>
</html>
