<!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>C++ Concurrent Buffer Queue</title>
</head>
<body>
<table style="margin-right: 0em">
<tbody>
<tr><th>Project:</th><td>ISO JTC1/SC22/WG21: Programming Language C++</td></tr>
<tr><th>Number:</th><td>P1958R0</td></tr>
<tr><th>Date:</th><td>2020-01-12</td></tr>
<tr><th>Audience:</th><td>LEWG</td></tr>
<tr><th>Revises:</th><td>P0260R3</td></tr>
<tr><th>Author:</th><td>Lawrence Crowl, Chris Mysen</td></tr>
<tr><th>Contact:</th><td>Lawrence@Crowl.org</td></tr>
</tbody>
</table>


<h1>C++ Concurrent Buffer Queue</h1>

<p>
Lawrence Crowl, Chris Mysen
</p>


<h2>Abstract</h2>

<p>
Concurrent queues are a fundamental structuring tool for concurrent programs.
We propose a concrete concurrent queue, based on a fixed-size buffer,
that meets the concepts described in
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0260r4.html">P0260R4</a>.
</p>


<h2>Contents</h2>



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

<p>
Queues provide a mechanism
for communicating data between components of a system.
</p>

<p>
We propose a concrete concurrent queue, based on a fixed-size buffer,
that meets the concepts described in
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0260r4.html">P0260R4</a>.
</p>


<h2><a name="buffer_queue">Locking Buffer Queue</a></h2>

<p>
We provide a concrete concurrent queue
in the form of a fixed-size <code>buffer_queue</code>.
It meets the <code>WaitingConcurrentQueue</code> concept.
It provides for construction of an empty queue,
and construction of a queue from a pair of iterators.
Constructors take a parameter
specifying the maximum number of elements in the buffer.
Constructors may also take a parameter
specifying the name of the queue.
If the name is not present, it defaults to the empty string.
</p>

<p>
The <code>buffer_queue</code>
deletes the default constructor, the copy constructor,
and the copy assignment operator.
We feel that their benefit might not justify their potential confusion.
</p>


<h2><a name="Wording">Proposed Wording</a></h2>

<p>
The concurrent queue container definition is as follows.
The section, paragraph, and table references
are based on those of
<cite><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4567.pdf"> N4567</a>
Working Draft, Standard for Programming Language C++</cite>,
Richard Smith, November 2015.
</p>


<h3><a name="conqueues">?.? Concurrent queues [conqueues]</a></h3>

<p>
Section added by 
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0260r4.html">P0260R4</a>.
</p>


<p>
Section added by 
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0260r4.html">P0260R4</a>.
</p>

<h3><a name="conqueues.concrete">?.?.5 Concrete queues [conqueues.concrete]</a></h3>

<p>
Add a new section:
</p>

<blockquote class="stdins">
<p>
There is one concrete concurrent queue type.
</p>
</blockquote>


<h3><a name="conqueues.concrete.buffer">?.?.5.1 Class template <code>buffer_queue</code>[conqueues.concrete.buffer]</a></h3>

<p>
Add a new section:
</p>

<blockquote class="stdins">

<pre>template &lt;typename Value&gt;
class buffer_queue
{
  buffer_queue() = delete;
  buffer_queue(const buffer_queue&amp;) = delete;
  buffer_queue&amp; operator =(const buffer_queue&amp;) = delete;
public:
  typedef Value value_type;
  explicit buffer_queue(size_t max_elems);
  template &lt;typename Iter&gt;
  buffer_queue(size_t max_elems, Iter first, Iter last);
  ~buffer_queue() noexcept;

  void close() noexcept;
  bool is_closed() const noexcept;
  bool is_empty() const noexcept;
  bool is_full() const noexcept;
  static bool is_lock_free() noexcept;

  Value value_pop();
  queue_op_status wait_pop(Value&amp;);
  queue_op_status try_pop(Value&amp;);

  void push(const Value&amp; x);
  queue_op_status wait_push(const Value&amp; x);
  queue_op_status try_push(const Value&amp; x);
  void push(Value&amp;&amp; x);
  queue_op_status wait_push(Value&amp;&amp; x);
  queue_op_status try_push(Value&amp;&amp; x);
};
</pre>

<p>
The class template <code>buffer_queue</code>
implements the <code>WaitingConcurrentQueue</code> concept.
The class template <code>buffer_queue</code>
provides a FIFO ordering.
That is, the sequentially consistent order of pushes
is the same as the sequentially consistet order of pops.
(See the synchronization of <code>push</code> [conqueues.concept.wait].)
</p>

<p class="function">
<code>buffer_queue(size_t max_elems);</code>
</p>

<dl class="attribute">
<dt>Effects:</dt>
<dd><p>
Constructs the queue with a buffer capacity of <code>max_elems</code>.
</p></dd>

<dt>Throws:</dt>
<dd><p>
Any exception thrown by constructing the internal arrays or mutexes.
</p></dd>
</dl>

<p class="function">
<code>
template &lt;typename Iter&gt;
buffer_queue(size_t max_elems, Iter first, Iter last);
</code>
</p>

<dl class="attribute">
<dt>Effects:</dt>
<dd><p>
Constructs the queue with a buffer capacity of <code>max_elems</code>.
Initializes the internal array by iterating
from <code>first</code> to <code>last</code>.
</p></dd>

<dt>Throws:</dt>
<dd><p>
Any exception thrown by constructing the internal arrays or mutexes.
</p></dd>
</dl>

<p class="function">
<code>~buffer_queue() noexcept;</code>
</p>

<dl class="attribute">
<dt>Effects:</dt>
<dd><p>
Destroys the queue.
Any elements remaining within the queue are discarded.
</p></dd>

</dl>

</blockquote>


<h2><a name="Revision">Revision History</a></h2>

<p>
This paper revises portions of
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0260r3.html">P0260R3</a>.
</p>


</body></html>
