<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2426: Issue about compare_exchange</title>
<meta property="og:title" content="Issue 2426: Issue about compare_exchange">
<meta property="og:description" content="C++ library issue. Status: C++17">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2426.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#C++17">C++17</a> status.</em></p>
<h3 id="2426"><a href="lwg-defects.html#2426">2426</a>. Issue about <code>compare_exchange</code></h3>
<p><b>Section:</b> 32.5.8.2 <a href="https://wg21.link/atomics.types.operations">[atomics.types.operations]</a> <b>Status:</b> <a href="lwg-active.html#C++17">C++17</a>
 <b>Submitter:</b> Hans Boehm <b>Opened:</b> 2014-08-25 <b>Last modified:</b> 2017-07-30</p>
<p><b>Priority: </b>1
</p>
<p><b>View other</b> <a href="lwg-index-open.html#atomics.types.operations">active issues</a> in [atomics.types.operations].</p>
<p><b>View all other</b> <a href="lwg-index.html#atomics.types.operations">issues</a> in [atomics.types.operations].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#C++17">C++17</a> status.</p>
<p><b>Discussion:</b></p>
<p>
The standard is either ambiguous or misleading about the nature of accesses through the <code>expected</code> argument 
to the <code>compare_exchange_*</code> functions in 99 [atomics.types.operations.req]p21.
<p/>
It is unclear whether the access to <code>expected</code> is itself atomic (intent clearly no) and exactly when the implementation 
is allowed to read or write it. These affect the correctness of reasonable code.
<p/>
Herb Sutter, summarizing a complaint from Duncan Forster wrote:
</p>
<blockquote class="note">
<p>
Thanks Duncan,
<p/>
I think we have a bug in the standardese wording and the implementations are
legal, but let's check with the designers of the feature.
<p/>
Let me try to summarize the issue as I understand it:
</p>
<ol>
<li><p>
What I think was intended: Lawrence, I believe you championed having
<code>compare_exchange_*</code> take the <code>expected</code> value by reference, and update
<code>expected</code> on failure to expose the old value, but this was only for convenience
to simplify the calling loops which would otherwise always have to write an
extra "reload" line of code. Lawrence, did I summarize your intent correctly?
</p></li>
<li><p>
What I think Duncan is trying to do: However, it turns out that, now that
<code>expected</code> is an lvalue, it has misled(?) Duncan into trying to use the success of
<code>compare_exchange_*</code> to hand off ownership <em>of <code>expected</code> itself</em> to another
thread. For that to be safe, if the <code>compare_exchange_*</code> succeeds then the
thread that performed it must no longer read or write from <code>expected</code> else his
technique contains a race. Duncan, did I summarize your usage correctly? Is
that the only use that is broken?
</p></li>
<li><p>
What the standard says: I can see why Duncan thinks the standard supports
his use, but I don't think this was intended (I don't remember this being
discussed but I may have been away for that part) and unless you tell me this
was intended I think it's a defect in the standard. From 99 [atomics.types.operations.req]/21:
</p>
<blockquote><p>
-21- <i>Effects</i>: Atomically, compares the contents of the memory pointed to by
<code>object</code> or by <code>this</code> for equality with that in <code>expected</code>, and if true, replaces the
contents of the memory pointed to by <code>object</code> or by <code>this</code> with that in <code>desired</code>, and
if false, updates the contents of the memory in <code>expected</code> with the contents of
the memory pointed to by <code>object</code> or by <code>this</code>. [&hellip;]
</p></blockquote>
<p>
I think we have a wording defect here in any case, because the "atomically"
should not apply to the entire sentence &mdash; I'm pretty sure we never intended the
atomicity to cover the write to <code>expected</code>.
<p/>
As a case in point, borrowing from Duncan's mail below, I think the following
implementation is intended to be legal:
</p>
<blockquote><pre>
inline int _Compare_exchange_seq_cst_4(volatile _Uint4_t *_Tgt, _Uint4_t *_Exp, _Uint4_t _Value)
{ /* compare and exchange values atomically with
     sequentially consistent memory order */
  int _Res;
  _Uint4_t _Prev = _InterlockedCompareExchange((volatile long *)_Tgt, _Value, *_Exp);
  <span style="color:#C80000">if (_Prev == *_Exp) //!!!!! Note the unconditional read from *_Exp here</span>
    _Res = 1;
  else
  { /* copy old value */
    _Res = 0;
    *_Exp = _Prev;
  }
  return (_Res);
}
</pre></blockquote>
<p>
I think this implementation is intended to be valid &mdash; I think the only code that
could be broken with the "!!!!!" read of <code>*_Exp</code> is Duncan's use of treating
<code>a.compare_exchange_*(expected, desired) == true</code> as implying <code>expected</code> got
handed off, because then another thread could validly be using <code>*_Exp</code> &mdash; but we
never intended this use, right?
</p>
</li>
</ol>
</blockquote>
<p>
In a different thread Richard Smith wrote about the same problem:
</p>
<blockquote class="note">
<p>
The <code>atomic_compare_exchange</code> functions are described as follows:
</p>
<blockquote><p>
"Atomically, compares the contents of the memory pointed to by <code>object</code> or by <code>this</code> 
for equality with that in <code>expected</code>, and if true, replaces the contents of the memory pointed to 
by <code>object</code> or by <code>this</code> with that in <code>desired</code>, and if false, updates the contents 
of the memory in <code>expected</code> with the contents of the memory 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>."
</p></blockquote>
<p>
I think this is less clear than it could be about the effects of these operations on <code>*expected</code> in the failure case:
</p>
<ol>
<li><p>We have "Atomically, compares [&hellip;] and updates the contents of the memory in <code>expected</code> [&hellip;]". 
The update to the memory in <code>expected</code> is clearly not atomic, and yet this wording parallels the success case, 
in which the memory update is atomic.
</p></li>
<li><p>The wording suggests that memory (including <code>*expected</code>) is affected according to the value of <code>failure</code>. 
In particular, the failure order could be <code>memory_order_seq_cst</code>, which might lead someone to incorrectly think they'd 
published the value of <code>*expected</code>.</p></li>
</ol>
<p>
I think this can be clarified with no change in meaning by reordering the wording a little:
</p>
<blockquote><p>
"Atomically, compares the contents of the memory pointed to by <code>object</code> or by <code>this</code> for equality with that in 
<code>expected</code>, and if true, replaces the contents of the memory pointed to by <code>object</code> or by <code>this</code> with 
that in <code>desired</code><del>, and if</del><ins>. 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>. Further, 
if the comparison is</ins> false, <del>updates</del><ins>replaces</ins> the contents of the memory in <code>expected</code> with 
the <del>contents of</del><ins>value that was atomically read from</ins> the memory pointed to by <code>object</code> or by 
<code>this</code>. <del>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>.</del>"
</p></blockquote>
</blockquote>
<p>
Jens Maurer add:
</p>
<blockquote class="note">
<p>
I believe this is an improvement.
<p/>
I like to see the following additional improvements:
</p>
<ul>
<li><p>
"contents of the memory" is strange phrasing, which doesn't say how large the
memory block is. Do we compare the values or the value representation of the lvalue
<code>*object</code> (or <code>*this</code>)?
</p></li>
<li><p>
32.5.4 <a href="https://wg21.link/atomics.order">[atomics.order]</a> defines memory order based on the "affected memory location". It would be
better to say something like "If the comparison is true, the memory synchronization order for the 
affected memory location <code>*object</code> is [&hellip;]"
</p></li>
</ul>
</blockquote>
<p>
There was also a discussion thread involving Herb Sutter, Hans Boehm, and Lawrence Crowl, resulting in proposed 
wording along the lines of:
</p>
<blockquote class="note">
<blockquote>
<p>
-21- <i>Effects</i>: Atomically with respect to <code>expected</code> and the memory pointed
to by <code>object</code> or by <code>this</code>, compares the contents of the memory pointed
to by <code>object</code> or by <code>this</code> for equality with that in <code>expected</code>, and if and
only if true, replaces the contents of the memory pointed to by <code>object</code>
or by <code>this</code> with that in desired, and if and only if false, updates the
contents of the memory in expected with the contents of the memory pointed to by 
<code>object</code> or by <code>this</code>.
</p>
</blockquote>
<p>
At the end of paragraph 23, perhaps add
</p>
<blockquote>
<p>
[<i>Example</i>: Because the <code>expected</code> value is updated only on failure,
code releasing the memory containing the <code>expected</code> value on success
will work. E.g. list head insertion will act atomically and not
have a data race in the following code.
</p>
<blockquote><pre>
do {
  p->next = head; // make new list node point to the current head
} while(!head.compare_exchange_weak(p->next, p)); // try to insert
</pre></blockquote>
<p>
&mdash; <i>end example</i>]
</p>
</blockquote>
</blockquote>
<p>
Hans objected that this still gives the misimpression that the update to <code>expected</code> is atomic.
</p>

<p><i>[2014-11 Urbana]</i></p>

<p>
Proposed resolution was added after Redmond.
</p>
<p>
Recommendations from SG1:
</p>
<ol>
<li>Change wording to <del>if true</del><ins>if and only if true</ins>, and change <del>if false</del><ins>if and only if false</ins>.</li>
<li>If they want to add "respect to" clause, say "respect to object or this".</li>
<li>In example, load from head should be "head.load(memory_order_relaxed)", because people are going to use example as example of good code.</li>
</ol>

<p>
<i>(wording edits not yet applied)</i>
</p>

<p><i>[2015-02 Cologne]</i></p>

<p>
Handed over to SG1.
</p>

<p><i>[2015-05 Lenexa, SG1 response]</i></p>

<p>
We believed we were done with it, but it was kicked back to us, with the wording we suggested not yet applied.  It may have been that our suggestions were unclear.  Was that the concern?
</p>

<p><i>[2016-02 Jacksonville]</i></p>

<p>
Applied the other half of the "if and only if" response from SG1, and moved to Ready.
</p>



<p id="res-2426"><b>Proposed resolution:</b></p>

<ol>
<li><p>Edit 99 [atomics.types.operations.req] p21 as indicated:</p>

<blockquote>
<p>
-21- <i>Effects</i>: <ins>Retrieves the value in <code>expected</code>. It then a</ins><del>A</del>tomically<del>,</del> 
compares the contents of the memory pointed to by <code>object</code> or by <code>this</code> for equality with that 
<del>in</del><ins>previously retrieved from</ins> <code>expected</code>, and if true, replaces the contents of the 
memory pointed to by <code>object</code> or by <code>this</code> with that in <code>desired</code><del>, and if false, 
updates the contents of the memory in expected with the contents of the memory pointed to by <code>object</code> 
or by <code>this</code>. Further, if</del><ins>. If and only if</ins> 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 and only if the comparison is false then, after the atomic
operation, the contents of the memory in <code>expected</code> are replaced by the value read from <code>object</code> or
by <code>this</code> during the atomic comparison.</ins> If the operation returns true, these operations are
atomic read-modify-write operations (1.10) <ins>on the memory pointed to by <code>this</code> or 
<code>object</code></ins>. Otherwise, these operations are atomic load operations <ins>on that memory</ins>.
</p>
</blockquote>
</li>

<li><p>Add the following example to the end of 99 [atomics.types.operations.req] p23:</p>

<blockquote>
<p>
-23- [<i>Note</i>: [&hellip;] &mdash; <i>end note</i>] [<i>Example</i>: [&hellip;] &mdash; <i>end example</i>]
<p/>
<ins>[<i>Example</i>: Because the expected value is updated only on failure,
code releasing the memory containing the <code>expected</code> value
on success will work. E.g. list head insertion will act atomically
and would not introduce a data race in the following code:</ins>
</p>
<blockquote>
<pre><ins>
do {
  p-&gt;next = head; // make new list node point to the current head
} while(!head.compare_exchange_weak(p-&gt;next, p)); // try to insert
</ins></pre>
</blockquote>
<p>
<ins>&mdash; <i>end example</i>]</ins>
</p>
</blockquote>
</li>
</ol>






</body>
</html>
