<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 926: Sequentially consistent fences, relaxed operations and modification order</title>
<meta property="og:title" content="Issue 926: Sequentially consistent fences, relaxed operations and modification order">
<meta property="og:description" content="C++ library issue. Status: NAD Editorial">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue926.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_Editorial">NAD Editorial</a> status.</em></p>
<h3 id="926"><a href="lwg-closed.html#926">926</a>. Sequentially consistent fences, relaxed operations and modification order</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_Editorial">NAD Editorial</a>
 <b>Submitter:</b> Anthony Williams <b>Opened:</b> 2008-10-19 <b>Last modified:</b> 2016-01-28</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#NAD Editorial">NAD Editorial</a> status.</p>
<p><b>Discussion:</b></p>
<p><b>Addresses UK 313</b></p>

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

<blockquote><pre>
// 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
</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 32.5.4 <a href="https://wg21.link/atomics.order">[atomics.order]</a>p5 from
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/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 32.5.4 <a href="https://wg21.link/atomics.order">[atomics.order]</a>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 32.5.4 <a href="https://wg21.link/atomics.order">[atomics.order]</a>:
</p>
<blockquote><p>
[Note: <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.]
</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><i>[
2009-10 Santa Cruz:
]</i></p>


<blockquote><p>
NAD Editorial.  Solved by
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2992.html">N2992</a>.
</p></blockquote>



<p id="res-926"><b>Proposed resolution:</b></p>
<p>
Add a new paragraph after 32.5.4 <a href="https://wg21.link/atomics.order">[atomics.order]</a>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>





</body>
</html>
