<html>
<head>
<title>P2066R1: Suggested draft TS for C++ Extensions for Minimal Transactional Memory</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 P2066R1<br/>
Authors: Hans Boehm, Victor Luchangco, Jens Maurer, Michael L. Scott, Michael Spear, and Michael Wong<br/>
Reply to: Jens Maurer &lt;Jens.Maurer@gmx.net><br/>
Target audience: SG1, EWG<br/>
2020-02-15<br/>

<h1>P2066R1: Suggested draft TS for C++ Extensions for Minimal Transactional Memory</h1>

<h2>Introduction</h2>

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

<h2>Changes in R1 since R0</h2>
<ul>
  <li>incorporated feedback from SG1 in Prague</li>
</ul>

<h2>Wording changes</h2>

These wording changes are relative to the current C++ Working Draft, N4849.
<p>
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
a <strong>transaction</strong>. [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 <strong>transactions</strong>. If, in that total order,
a transaction T1 is ordered before a transaction T2, then
<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, A strongly happens before some
evaluation B, <strong>and B is not sequenced before the end of T</strong>,
then the end of T strongly happens before B. If an
evaluation C strongly happens before that evaluation A
<strong>and C is not sequenced after the start of T</strong>, 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>

<strong>Change in 6.9.2.2 [intro.progress] paragraph 1:</strong>

<blockquote>
  <del>The implementation may assume that any thread will eventually do</del>
  <ins>An <em>inter-thread side effect</em> is</ins> one
  of the following:
<ul>
  <li>a call to a library I/O function,</li>
  <li>an access through a volatile glvalue, or</li>
  <li>a synchronization operation or an atomic operation.</li>
</ul>
<ins>The implementation may assume that any thread will eventually
terminate or evaluate an inter-thread side effect.</ins>
[Note: This is intended to allow compiler transformations such as
removal of empty loops, even when termination cannot be proven. — 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>
<strong>If the execution of an atomic block evaluates an inter-thread side
effect (6.9.2.2 [intro.progress]), the behavior is undefined.</strong>
<p>
If the execution of an atomic block evaluates any of the following,
the behavior is implementation-defined:
<ul>
  <li>an <em>asm-declaration</em> (9.10 [dcl.asm]);</li>
  <li>an invocation of a function other than an inline function with
    a reachable definition;</li>
  <li>a virtual function call (7.6.1.2 [expr.call]);</li>
  <li>a function call whose <em>postfix-expression</em> does
      not name a function (12.4.1.1 [over.match.call]);</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]),
  a <code>co_return</code> statement (8.7.4 [stmt.return.coroutine]),</li>
  <li><strong>dynamic initialization of a block-scope variable with static storage duration, or</strong></li>
  <li><strong>dynamic initialization of a variable with thread storage duration.</strong></li>
</ul>
[ Note: A standard library function not specified to be inline is
assumed not to be inline. A constexpr function is implicitly inline
(9.2.5 [dcl.constexpr]). ] [ 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>
