<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=US-ASCII">

<style type="text/css">

body { color: #000000; background-color: #FFFFFF; }
del { text-decoration: line-through; color: #8B0040; }
ins { text-decoration: underline; color: #005100; }

p.example { margin-left: 2em; }
pre.example { margin-left: 2em; }
div.example { margin-left: 2em; }

code.extract { background-color: #F5F6A2; }
pre.extract { margin-left: 2em; background-color: #F5F6A2;
  border: 1px solid #E1E28E; }

p.function { }
.attribute { margin-left: 2em; }
.attribute dt { float: left; font-style: italic;
  padding-right: 1ex; }
.attribute dd { margin-left: 0em; }

blockquote.std { color: #000000; background-color: #F1F1F1;
  border: 1px solid #D1D1D1;
  padding-left: 0.5em; padding-right: 0.5em; }
blockquote.stddel { text-decoration: line-through;
  color: #000000; background-color: #FFEBFF;
  border: 1px solid #ECD7EC;
  padding-left: 0.5empadding-right: 0.5em; ; }

blockquote.stdins { text-decoration: underline;
  color: #000000; background-color: #C8FFC8;
  border: 1px solid #B3EBB3; padding: 0.5em; }

table { border: 1px solid black; border-spacing: 0px;
  margin-left: auto; margin-right: auto; }
th { text-align: left; vertical-align: top;
  padding-left: 0.8em; border: none; }
td { text-align: left; vertical-align: top;
  padding-left: 0.8em; border: none; }

</style>


<title>Concurrency Safety in C++ Data Structures</title>
</head>
<body>
<h1>Concurrency Safety in C++ Data Structures</h1>

<p>
Committee: ISO/IEC JTC1 SC22 WG21 SG1 Concurrency<br>
Document Number: P0495r0<br>
Date: 2016-11-27<br>
Authors: Lawrence Crowl<br>
Reply To: Lawrence Crowl, Lawrence@Crowl.org
</p>

<p>
</p>


<h2><a name="Problem">Problem</a></h2>

<p>
Synchronization between operations
is an important property of concurrent data structures.
The correct use of these data structures
requires a specification of their synchronization.
</p>

<p>
The simplest concurrent data structures in C++ are the atomic types.
The atomic types take a function parameter to specify memory order.
They provide query functions returning whether they are lock-free or not.
</p>

<p>
Larger data structures
are unlikely to be able to efficiently take a function parameter.
Indeed, the data structure is often very carefully designed
to satisfy a given level of synchronization.
</p>

<p>
More importantly, atomic types are <em>implementation types</em>,
generally used as a direct tool the implementation of other abstractions.
For larger data structures,
we often want a concept that enables different implementations.
</p>

<p>
How do we specify synchronization in complex C++ data structures
so as to ensure that they are used safely?
</p>


<h2><a name="Memory">Memory Order</a></h2>

<p>
The atomic types take a function parameter to specify memory order.
Their representation does not change depending on the memory order,
so this specification works well for atomic types.
For more complex data structures, the representation may change.
</p>

<p>
Since most concurrent data structures will be implemented as class templates,
the strawman approach is to add a type parameter to the class template
to specify the memory order.
The libary would then use the template parameter as a specialization key
for selecting the data structure implementation.
</p>

<p>
Unfortunately, that type parameter is not visible
when the data structure itself becomes a parameter to another template.
Generally, this loss of information is a good thing.
It abstracts the essence of the service that the data structure provides,
allowing the concrete data structure to be easily replaced as needs evolve.
</p>

<p>
Unfortunately, the memory order guaranteed by a concurrent data structure
generally must be visible.
Or, more to the point, any order less than sequentially consistent
requires care and should be obvious to the programmer.
This implies that template parameter to the data structure
is not an adequate assurance of proper use
of non-sequentially consistent data structures.
</p>

<p>
The only mechanism to 'type check' a template type parameter
is the names and parameters of the operations applied to that parameter.
So, to catch an unexpected use of non-sequentially-consistent data structures
as a template parameter,
we must make the function signatures
different from a sequentially-consistent signatures.
</p>

<p>
The obvious signature change is to change the name of the functions.
We can do better.
Make the operations function templates
with the required memory order as a template parameter.
A default of sequentially consistent will serve most programmers,
who require the simplicity of sequential consistency,
without imposing any additional burden on the text of the program.
</p>

<p>
Clients requiring less than sequential consistency
can be satisfied with an implementation providing sequential consistency.
So, those implementations can essentially ignore the template parameter
in their implementations of operations.
</p>

<p>
What memory orders make sense
in larger data structures?
</p>

<p>
Most operations both read and write.
However, we do not want to call them read-modify-write operations
unless they meet the constraints of such operations.
</p>


<h2><a name="Other">Other Issues</a></h2>

<p>
Do we need to specify lock freedom?
Wait freedom?
Any thing else?
</p>


</body>
</html>
