<html>
<head>
<title>P2066R0: Suggested draft TS for C++ Extensions for Transaction Memory Light</title>

<style type="text/css">
  ins { text-decoration:none; font-weight:bold; background-color:#A0FFA0 }
  .new { text-decoration:none; font-weight:bold; background-color:#D0FFD0 }
  del { text-decoration:line-through; background-color:#FFA0A0 }  
  strong { font-weight: inherit; color: #2020ff }
  table, td, th { border: 1px solid black; border-collapse:collapse; padding: 5px }
</style>
</head>

<body>
ISO/IEC JTC1 SC22 WG21 P2066R0<br/>
Authors: Michael L. Scott<br/>
Reply to: Jens Maurer &lt;Jens.Maurer@gmx.net><br/>
Target audience: SG1, EWG<br/>
2020-01-13<br/>

<h1>P2066R0: Suggested draft TS for C++ Extensions for Transaction Memory Light</h1>

<h2>Introduction</h2>

This paper presents suggested wording for a future Technical
Specification on a lighter variant of Transactional Memory. See
P1875R0 "Transactional Memory Lite Support in C++" for discussion.

<h2>Acknowledgements</h2>

Thanks to Hans Boehm, Victor Luchangco, Michael Spear, and Michael Wong.

<h2>Wording changes</h2>

In 5.11 [lex.key], add <ins><code>atomic</code></ins> to table 5 [tab:lex:key].

<p>

Change in 6.9.2.1 [intro.races] paragraph 6:

<blockquote>
<ins>Atomic blocks as well
as</ins> <del>Certain</del> <ins>certain</ins> library
calls <ins>may</ins> <em>synchronize with</em> other <ins>atomic
blocks and</ins> library calls performed by another thread.
</blockquote>

Add a new paragraph after 6.9.2.1 [intro.races] paragraph 20:

<blockquote class="new">
The start and the end of each atomic block (8.8 [stmt.tx]) is a
full-expression (6.9.1 [intro.execution]). An atomic block that is not
dynamically nested within another atomic block is called an outer
block. [Note: Due to syntactic constraints, blocks cannot overlap
unless one is nested within the other.] There is a global total order
of execution for all outer blocks. If, in that total order, a transaction T1 is
ordered before a transaction T2,
<ul>
  <li>no evaluation in T2 happens before any evaluation in T1 and</li>
  <li>if T1 and T2 perform conflicting expression evaluations, then
  the end of T1 synchronizes with the start of T2.</li>
</ul>
</blockquote>
<blockquote>
Two actions are <em>potentially concurrent</em> if ...
</blockquote>

Change in 6.9.2.1 [intro.races] paragraph 21:

<blockquote>
... [Note: It can be shown that programs that correctly use
mutexes<ins>, atomic blocks,</ins>
and <code>memory_order::seq_cst</code> operations to prevent all data
races and use no other synchronization operations behave as if the
operations executed by their constituent threads were simply
interleaved, with each value computation of an object being taken from
the last side effect on that object in that interleaving. This is
normally referred to as "sequential consistency". ...
</blockquote>

Add a new paragraph after 6.9.2.1 [intro.races] paragraph 21:

<blockquote class="new">
[ Note: The following holds for a data-race-free program: If the start
of an atomic block T is sequenced before an evaluation A, A is
sequenced before the end of T, and A strongly happens before some
evaluation B, then the end of T strongly happens before B. If an
evaluation C strongly happens before that evaluation A, then C
strongly happens before the start of T. These properties in turn imply
that in any simple interleaved (sequentially consistent) execution,
the operations of each atomic block appear to be contiguous in the
interleaving. -- end note ]
</blockquote>

Add a production to the grammar in 8.1 [expr.pre]:

<blockquote>
  <pre>
<em>statement:
      labeled-statement
      attribute-specifier-seq<sub>opt</sub> expression-statement
      attribute-specifier-seq<sub>op</sub>t compound-statement
      attribute-specifier-seq<sub>opt</sub> selection-statement
      attribute-specifier-seq<sub>opt</sub> iteration-statement
      attribute-specifier-seq<sub>opt</sub> jump-statement
      declaration-statement
      attribute-specifier-seq<sub>opt</sub> try-block
      <ins>atomic-statement</ins></em>
</blockquote>

Add a new subclause before 8.8 [stmt.dcl]:

<blockquote class="new">
<b>8.8 Atomic statement [stmt.tx]</b>
<p>
<pre>
<em>atomic-statement:</em>
     atomic <em>compound-statement</em>
</pre>

An atomic statement is also called an atomic block.
<p>
The start of the atomic block is immediately before the
opening <code>{</code> of the <em>compound-statement</em>. The end of the
atomic block is immediately after the closing <code>}</code> of the
<em>compound-statement</em>. [ Note: Thus, variables with automatic
storage duration declared in the <em>compound-statement</em> are
destroyed prior to reaching the end of the atomic block; see 8.7
[stmt.jump]. -- end note ]
<p>
If the execution of an atomic block evaluates any of the following,
the behavior is implementation-defined:
<ul>
  <li>an access through a volatile glvalue;</li>
  <li>an invocation of a function other than a constexpr function with
  a reachable definition;</li>
  <li>a <em>throw-expression</em> (7.6.18 [expr.throw]); or</li>
  <li>a <code>co_await</code> expression (7.6.2.3 [expr.await]),
  a <em>yield-expression</em> (7.6.17 [expr.yield]), or
  a <code>co_return</code> statement (8.7.4
  [stmt.return.coroutine]).</li>
</ul>
[ Note: Locking a mutex, accessing an atomic variable, or performing
I/O invokes non-constexpr functions. ] [ Note: The implementation may
define that the behavior is undefined in some or all of the cases
above. ]
<p>
A goto or switch statement shall not be used to transfer control into
an atomic block.
<p>
[ Example:
<pre>
int f()
{
  static int i = 0;
  atomic {
    ++i;
    return i;
  }
}
</pre>
Each invocation of f (even when called from several threads
simultaneously) retrieves a unique value (ignoring overflow). -- end
example ]

<p>

</blockquote>

</body>
</html>
