<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 3980: The read exclusive ownership of an atomic read-modify-write operation and whether its read and write are two operations are unclear</title>
<meta property="og:title" content="Issue 3980: The read exclusive ownership of an atomic read-modify-write operation and whether its read and write are two operations are unclear">
<meta property="og:description" content="C++ library issue. Status: Tentatively NAD">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue3980.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#NAD">Tentatively NAD</a> status.</em></p>
<h3 id="3980"><a href="lwg-active.html#3980">3980</a>. The read exclusive ownership of an atomic read-modify-write operation and whether its read and write are two operations are unclear</h3>
<p><b>Section:</b> 32.5.4 <a href="https://wg21.link/atomics.order">[atomics.order]</a> <b>Status:</b> <a href="lwg-active.html#NAD">Tentatively NAD</a>
 <b>Submitter:</b> jim x <b>Opened:</b> 2023-08-22 <b>Last modified:</b> 2023-11-03</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View other</b> <a href="lwg-index-open.html#atomics.order">active issues</a> in [atomics.order].</p>
<p><b>View all other</b> <a href="lwg-index.html#atomics.order">issues</a> in [atomics.order].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#Tentatively NAD">Tentatively NAD</a> status.</p>
<p><b>Discussion:</b></p>
<p>
Such two questions are sourced from StackOverflow:
</p>
<ol>
<li><p><a href="https://stackoverflow.com/questions/77126045/can-the-read-operations-in-compare-exchange-strong-in-different-two-thread-rea/77126363?noredirect=1#comment135968355_77126363">Can the read operations in <code>compare_exchange_strong</code> in different two thread read the same value?</a></p></li>
<li><p><a href="https://stackoverflow.com/questions/65568185/for-purposes-of-ordering-is-atomic-read-modify-write-one-operation-or-two">For purposes of ordering, is atomic read-modify-write one operation or two?</a></p></li>
</ol>
<p>
Given this example:
</p>
<blockquote>
<pre>
#include &lt;iostream&gt;
#include &lt;atomic&gt;
#include &lt;thread&gt;

struct SpinLock{
  std::atomic&lt;bool&gt; atomic_;
  void lock(){
    bool expected = false;
    while (!atomic_.compare_exchange_strong(expected,true,std::memory_order_release,std::memory_order_relaxed)) {
    }
  }
  void unlock(){
    atomic_.store(false, std::memory_order_release);
  }
};

int main(){
  SpinLock spin{false};
  auto t1 = std::thread([&amp;](){
    spin.lock();
    spin.unlock();
  });
  auto t2 = std::thread([&amp;](){
    spin.lock();
    spin.unlock();
  });
  t1.join();
  t2.join();
}
</pre>
</blockquote>
<p>
In the current draft, the relevant phrasing that can interpret that only one read-modify-write operation reads the initial 
value false is 32.5.4 <a href="https://wg21.link/atomics.order">[atomics.order]</a> p10:
</p>
<blockquote style="border-left: 3px solid #ccc;padding-left: 15px;"><p>
Atomic read-modify-write operations shall always read the last value (in the modification order) written before the write 
associated with the read-modify-write operation.
</p></blockquote>
<p>
However, the wording can have two meanings, each kind of read can result in different explanations for the example
</p>
<ol>
<li><p>The check of the violation is done before the side effect of the RMW is in the modification order, i.e. the rule is 
just checked at the read point.</p></li>
<li><p>The check of the violation is done after the side effect of the RMW is in the modification order, i.e. the rule is 
checked when <code>RMW</code> tries to add the side effect that is based on the read-value to the modification order, and that 
side effect wouldn't be added to the modification order if the rule was violated.</p></li>
</ol>
<p>
With the first interpretation, the two RMW operations can read the same initial value because that value is indeed the last value 
in the modification order before such two RMW operations produce the side effect to the modification order.
<p/>
With the second interpretation, there is only one RMW operation that can read the initial value because the latter one in 
the modification order would violate the rule if it read the initial value.
<p/>
Such two interpretations arise from that the wording doesn't clearly specify when that check is performed.
<p/>
So, my proposed wording is:
</p>
<blockquote style="border-left: 3px solid #ccc;padding-left: 15px;"><p>
Atomic read-modify-write operations shall always read the value from a side effect <code>X</code>, where <code>X</code> 
immediately precedes the side effect of the read-modify-write operation in the modification order.
</p></blockquote>
<p>
This wording keeps a similar utterance to 6.10.2.2 <a href="https://wg21.link/intro.races">[intro.races]</a>, and it can clearly convey the meaning 
that we say the value read by <code>RWM</code> is associated with the side effect of <code>RMW</code> in the modification order.
<p/>
Relevant discussion can be seen <a href="https://github.com/cplusplus/CWG/issues/423">CWG/issues/423</a> here.
</p>

<p><i>[2023-11-03; Reflector poll]</i></p>

<p>NAD. The first reading isn't plausible. </p>



<p id="res-3980"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4958" title=" Working Draft, Programming Languages — C++">N4958</a>.
</p>

<ol>

<li><p>Modify 32.5.4 <a href="https://wg21.link/atomics.order">[atomics.order]</a> as indicated:</p>

<blockquote>
<p>
-10- Atomic read-modify-write operations shall always read the <del>last</del> value <ins>from a side effect <i>X</i>, 
where <i>X</i> immediately precedes the side effect of the read-modify-write operation</ins> <del>(</del>in the 
modification order<del>) written before the write associated with the read-modify-write operation</del>.
<p/>
-11- Implementations should make atomic stores visible to atomic loads within a reasonable amount of time.
</p>
</blockquote>

</li>

</ol>





</body>
</html>
