[DEV] add v1.76.0

This commit is contained in:
2021-10-05 21:37:46 +02:00
parent a97e9ae7d4
commit d0115b733d
45133 changed files with 4744437 additions and 1026325 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,152 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Limitations</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../atomic.html" title="Chapter 6. Boost.Atomic">
<link rel="prev" href="usage_examples.html" title="Usage examples">
<link rel="next" href="porting.html" title="Porting">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="usage_examples.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../atomic.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="porting.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="atomic.limitations"></a><a class="link" href="limitations.html" title="Limitations">Limitations</a>
</h2></div></div></div>
<p>
While <span class="bold"><strong>Boost.Atomic</strong></span> strives to implement the
atomic operations from C++11 and later as faithfully as possible, there are
a few limitations that cannot be lifted without compiler support:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<span class="bold"><strong>Aggregate initialization syntax is not supported</strong></span>:
Since <span class="bold"><strong>Boost.Atomic</strong></span> sometimes uses storage
type that is different from the value type, the <code class="computeroutput"><span class="identifier">atomic</span><span class="special">&lt;&gt;</span></code> template needs an initialization
constructor that performs the necessary conversion. This makes <code class="computeroutput"><span class="identifier">atomic</span><span class="special">&lt;&gt;</span></code>
a non-aggregate type and prohibits aggregate initialization syntax (<code class="computeroutput"><span class="identifier">atomic</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">a</span> <span class="special">=</span> <span class="special">{</span><span class="number">10</span><span class="special">}</span></code>).
<span class="bold"><strong>Boost.Atomic</strong></span> does support direct and unified
initialization syntax though. <span class="bold"><strong>Advice</strong></span>:
Always use direct initialization (<code class="computeroutput"><span class="identifier">atomic</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">a</span><span class="special">(</span><span class="number">10</span><span class="special">)</span></code>)
or unified initialization (<code class="computeroutput"><span class="identifier">atomic</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">a</span><span class="special">{</span><span class="number">10</span><span class="special">}</span></code>)
syntax.
</li>
<li class="listitem">
<span class="bold"><strong>Initializing constructor is not <code class="computeroutput"><span class="keyword">constexpr</span></code>
for some types</strong></span>: For value types other than integral types and
<code class="computeroutput"><span class="keyword">bool</span></code>, <code class="computeroutput"><span class="identifier">atomic</span><span class="special">&lt;&gt;</span></code> initializing constructor needs
to perform runtime conversion to the storage type. This limitation may
be lifted for more categories of types in the future.
</li>
<li class="listitem">
<span class="bold"><strong>Default constructor is not trivial in C++03</strong></span>:
Because the initializing constructor has to be defined in <code class="computeroutput"><span class="identifier">atomic</span><span class="special">&lt;&gt;</span></code>,
the default constructor must also be defined. In C++03 the constructor
cannot be defined as defaulted and therefore it is not trivial. In C++11
the constructor is defaulted (and trivial, if the default constructor of
the value type is). In any case, the default constructor of <code class="computeroutput"><span class="identifier">atomic</span><span class="special">&lt;&gt;</span></code>
performs default initialization of the atomic value, as required in C++11.
<span class="bold"><strong>Advice</strong></span>: In C++03, do not use <span class="bold"><strong>Boost.Atomic</strong></span> in contexts where trivial default constructor
is important (e.g. as a global variable which is required to be statically
initialized).
</li>
<li class="listitem">
<span class="bold"><strong>C++03 compilers may transform computation dependency
to control dependency</strong></span>: Crucially, <code class="computeroutput"><span class="identifier">memory_order_consume</span></code>
only affects computationally-dependent operations, but in general there
is nothing preventing a compiler from transforming a computation dependency
into a control dependency. A fully compliant C++11 compiler would be forbidden
from such a transformation, but in practice most if not all compilers have
chosen to promote <code class="computeroutput"><span class="identifier">memory_order_consume</span></code>
to <code class="computeroutput"><span class="identifier">memory_order_acquire</span></code>
instead (see <a href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59448" target="_top">this</a>
gcc bug for example). In the current implementation <span class="bold"><strong>Boost.Atomic</strong></span>
follows that trend, but this may change in the future. <span class="bold"><strong>Advice</strong></span>:
In general, avoid <code class="computeroutput"><span class="identifier">memory_order_consume</span></code>
and use <code class="computeroutput"><span class="identifier">memory_order_acquire</span></code>
instead. Use <code class="computeroutput"><span class="identifier">memory_order_consume</span></code>
only in conjunction with pointer values, and only if you can ensure that
the compiler cannot speculate and transform these into control dependencies.
</li>
<li class="listitem">
<span class="bold"><strong>Fence operations may enforce "too strong"
compiler ordering</strong></span>: Semantically, <code class="computeroutput"><span class="identifier">memory_order_acquire</span></code>/<code class="computeroutput"><span class="identifier">memory_order_consume</span></code> and <code class="computeroutput"><span class="identifier">memory_order_release</span></code> need to restrain
reordering of memory operations only in one direction. Since in C++03 there
is no way to express this constraint to the compiler, these act as "full
compiler barriers" in C++03 implementation. In corner cases this may
result in a slightly less efficient code than a C++11 compiler could generate.
<span class="bold"><strong>Boost.Atomic</strong></span> will use compiler intrinsics,
if possible, to express the proper ordering constraints.
</li>
<li class="listitem">
<span class="bold"><strong>Atomic operations may enforce "too strong"
memory ordering in debug mode</strong></span>: On some compilers, disabling
optimizations makes it impossible to provide memory ordering constraints
as compile-time constants to the compiler intrinsics. This causes the compiler
to silently ignore the provided constraints and choose the "strongest"
memory order (<code class="computeroutput"><span class="identifier">memory_order_seq_cst</span></code>)
to generate code. Not only this reduces performance, this may hide bugs
in the user's code (e.g. if the user used a wrong memory order constraint,
which caused a data race). <span class="bold"><strong>Advice</strong></span>: Always
test your code with optimizations enabled.
</li>
<li class="listitem">
<span class="bold"><strong>No interprocess fallback</strong></span>: using <code class="computeroutput"><span class="identifier">atomic</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
in shared memory only works correctly, if <code class="computeroutput"><span class="identifier">atomic</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">is_lock_free</span><span class="special">()</span> <span class="special">==</span> <span class="keyword">true</span></code>.
Same with <code class="computeroutput"><span class="identifier">atomic_ref</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>.
</li>
<li class="listitem">
<span class="bold"><strong>Signed integers must use <a href="https://en.wikipedia.org/wiki/Two%27s_complement" target="_top">two's
complement</a> representation</strong></span>: <span class="bold"><strong>Boost.Atomic</strong></span>
makes this requirement in order to implement conversions between signed
and unsigned integers internally. C++11 requires all atomic arithmetic
operations on integers to be well defined according to two's complement
arithmetics, which means that <span class="bold"><strong>Boost.Atomic</strong></span>
has to operate on unsigned integers internally to avoid undefined behavior
that results from signed integer overflows. Platforms with other signed
integer representations are not supported. Note that C++20 makes two's
complement representation of signed integers mandatory.
</li>
<li class="listitem">
<span class="bold"><strong>Types with padding bits are not supported</strong></span>:
As discussed in <a class="link" href="interface.html#atomic.interface.interface_atomic_ref.caveats" title="Caveats">this
section</a>, <span class="bold"><strong>Boost.Atomic</strong></span> cannot support
types with padding bits because their content is undefined, and there is
no portable way to initialize them to a predefined value. This makes operations
like <code class="computeroutput"><span class="identifier">compare_exchange_strong</span></code>/<code class="computeroutput"><span class="identifier">compare_exchange_weak</span></code> fail, and given
that in some cases other operations are built upon these, potentially all
operations become unreliable. <span class="bold"><strong>Boost.Atomic</strong></span>
does support padding bits for floating point types on platforms where the
location of the padding bits is known at compile time.
</li>
</ul></div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2011 Helge Bahmann<br>Copyright © 2012 Tim Blechmann<br>Copyright © 2013, 2017, 2018, 2020 Andrey
Semashev<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="usage_examples.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../atomic.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="porting.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,150 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Porting</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../atomic.html" title="Chapter 6. Boost.Atomic">
<link rel="prev" href="limitations.html" title="Limitations">
<link rel="next" href="../chrono.html" title="Chapter 7. Boost.Chrono 2.0.8">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="limitations.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../atomic.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../chrono.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="atomic.porting"></a><a class="link" href="porting.html" title="Porting">Porting</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="porting.html#atomic.porting.unit_tests">Unit tests</a></span></dt>
<dt><span class="section"><a href="porting.html#atomic.porting.tested_compilers">Tested compilers</a></span></dt>
<dt><span class="section"><a href="porting.html#atomic.porting.acknowledgements">Acknowledgements</a></span></dt>
</dl></div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="atomic.porting.unit_tests"></a><a class="link" href="porting.html#atomic.porting.unit_tests" title="Unit tests">Unit tests</a>
</h3></div></div></div>
<p>
<span class="bold"><strong>Boost.Atomic</strong></span> provides a unit test suite
to verify that the implementation behaves as expected:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<span class="bold"><strong>atomic_api.cpp</strong></span> and <span class="bold"><strong>atomic_ref_api.cpp</strong></span>
verifies that all atomic operations have correct value semantics (e.g.
"fetch_add" really adds the desired value, returning the previous).
The latter tests <code class="computeroutput"><span class="identifier">atomic_ref</span></code>
rather than <code class="computeroutput"><span class="identifier">atomic</span></code> and
<code class="computeroutput"><span class="identifier">atomic_flag</span></code>. It is a
rough "smoke-test" to help weed out the most obvious mistakes
(for example width overflow, signed/unsigned extension, ...). These tests
are also run with <code class="computeroutput"><span class="identifier">BOOST_ATOMIC_FORCE_FALLBACK</span></code>
macro defined to test the lock pool based implementation.
</li>
<li class="listitem">
<span class="bold"><strong>lockfree.cpp</strong></span> verifies that the <span class="bold"><strong>BOOST_ATOMIC_*_LOCKFREE</strong></span> macros are set properly
according to the expectations for a given platform, and that they match
up with the <span class="bold"><strong>is_always_lock_free</strong></span> and
<span class="bold"><strong>is_lock_free</strong></span> members of the <span class="bold"><strong>atomic</strong></span> object instances.
</li>
<li class="listitem">
<span class="bold"><strong>atomicity.cpp</strong></span> and <span class="bold"><strong>atomicity_ref.cpp</strong></span>
lets two threads race against each other modifying a shared variable,
verifying that the operations behave atomic as appropriate. By nature,
this test is necessarily stochastic, and the test self-calibrates to
yield 99% confidence that a positive result indicates absence of an error.
This test is very useful on uni-processor systems with preemption already.
</li>
<li class="listitem">
<span class="bold"><strong>ordering.cpp</strong></span> and <span class="bold"><strong>ordering_ref.cpp</strong></span>
lets two threads race against each other accessing multiple shared variables,
verifying that the operations exhibit the expected ordering behavior.
By nature, this test is necessarily stochastic, and the test attempts
to self-calibrate to yield 99% confidence that a positive result indicates
absence of an error. This only works on true multi-processor (or multi-core)
systems. It does not yield any result on uni-processor systems or emulators
(due to there being no observable reordering even the order=relaxed case)
and will report that fact.
</li>
<li class="listitem">
<span class="bold"><strong>wait_api.cpp</strong></span> and <span class="bold"><strong>wait_ref_api.cpp</strong></span>
are used to verify waiting and notifying operations behavior. Due to
the possibility of spurious wakeups, these tests may fail if a waiting
operation returns early a number of times. The test retries for a few
times in this case, but a failure is still possible.
</li>
<li class="listitem">
<span class="bold"><strong>wait_fuzz.cpp</strong></span> is a fuzzing test for
waiting and notifying operations, that creates a number of threads that
block on the same atomic object and then wake up one or all of them for
a number of times. This test is intended as a smoke test in case if the
implementation has long-term instabilities or races (primarily, in the
lock pool implementation).
</li>
<li class="listitem">
<span class="bold"><strong>ipc_atomic_api.cpp</strong></span>, <span class="bold"><strong>ipc_atomic_ref_api.cpp</strong></span>,
<span class="bold"><strong>ipc_wait_api.cpp</strong></span> and <span class="bold"><strong>ipc_wait_ref_api.cpp</strong></span>
are similar to the tests without the <span class="bold"><strong>ipc_</strong></span>
prefix, but test IPC atomic types.
</li>
</ul></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="atomic.porting.tested_compilers"></a><a class="link" href="porting.html#atomic.porting.tested_compilers" title="Tested compilers">Tested compilers</a>
</h3></div></div></div>
<p>
<span class="bold"><strong>Boost.Atomic</strong></span> has been tested on and is known
to work on the following compilers/platforms:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
gcc 4.4 and newer: i386, x86_64, ppc32, ppc64, sparcv9, armv6, alpha
</li>
<li class="listitem">
clang 3.5 and newer: i386, x86_64
</li>
<li class="listitem">
Visual Studio Express 2008 and newer on Windows XP and later: x86, x64,
ARM
</li>
</ul></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="atomic.porting.acknowledgements"></a><a class="link" href="porting.html#atomic.porting.acknowledgements" title="Acknowledgements">Acknowledgements</a>
</h3></div></div></div>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
Adam Wulkiewicz created the logo used on the <a href="https://github.com/boostorg/atomic" target="_top">GitHub
project page</a>. The logo was taken from his <a href="https://github.com/awulkiew/boost-logos" target="_top">collection</a>
of Boost logos.
</li></ul></div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2011 Helge Bahmann<br>Copyright © 2012 Tim Blechmann<br>Copyright © 2013, 2017, 2018, 2020 Andrey
Semashev<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="limitations.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../atomic.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../chrono.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,386 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Thread coordination using Boost.Atomic</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../atomic.html" title="Chapter 6. Boost.Atomic">
<link rel="prev" href="../atomic.html" title="Chapter 6. Boost.Atomic">
<link rel="next" href="interface.html" title="Programming interfaces">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../atomic.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../atomic.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="interface.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="atomic.thread_coordination"></a><a class="link" href="thread_coordination.html" title="Thread coordination using Boost.Atomic">Thread coordination using Boost.Atomic</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="thread_coordination.html#atomic.thread_coordination.mutex">Enforcing <span class="emphasis"><em>happens-before</em></span>
through mutual exclusion</a></span></dt>
<dt><span class="section"><a href="thread_coordination.html#atomic.thread_coordination.release_acquire"><span class="emphasis"><em>happens-before</em></span>
through <code class="literal">release</code> and <code class="literal">acquire</code></a></span></dt>
<dt><span class="section"><a href="thread_coordination.html#atomic.thread_coordination.fences">Fences</a></span></dt>
<dt><span class="section"><a href="thread_coordination.html#atomic.thread_coordination.release_consume"><span class="emphasis"><em>happens-before</em></span>
through <code class="literal">release</code> and <code class="literal">consume</code></a></span></dt>
<dt><span class="section"><a href="thread_coordination.html#atomic.thread_coordination.seq_cst">Sequential consistency</a></span></dt>
</dl></div>
<p>
The most common use of <span class="bold"><strong>Boost.Atomic</strong></span> is to
realize custom thread synchronization protocols: The goal is to coordinate
accesses of threads to shared variables in order to avoid "conflicts".
The programmer must be aware of the fact that compilers, CPUs and the cache
hierarchies may generally reorder memory references at will. As a consequence
a program such as:
</p>
<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">x</span> <span class="special">=</span> <span class="number">0</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">y</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
<span class="identifier">thread1</span><span class="special">:</span>
<span class="identifier">x</span> <span class="special">=</span> <span class="number">1</span><span class="special">;</span>
<span class="identifier">y</span> <span class="special">=</span> <span class="number">1</span><span class="special">;</span>
<span class="identifier">thread2</span><span class="special">:</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">y</span> <span class="special">==</span> <span class="number">1</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">x</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
might indeed fail as there is no guarantee that the read of <code class="computeroutput"><span class="identifier">x</span></code>
by thread2 "sees" the write by thread1.
</p>
<p>
<span class="bold"><strong>Boost.Atomic</strong></span> uses a synchronisation concept
based on the <span class="emphasis"><em>happens-before</em></span> relation to describe the guarantees
under which situations such as the above one cannot occur.
</p>
<p>
The remainder of this section will discuss <span class="emphasis"><em>happens-before</em></span>
in a "hands-on" way instead of giving a fully formalized definition.
The reader is encouraged to additionally have a look at the discussion of the
correctness of a few of the <a class="link" href="usage_examples.html" title="Usage examples">examples</a>
afterwards.
</p>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="atomic.thread_coordination.mutex"></a><a class="link" href="thread_coordination.html#atomic.thread_coordination.mutex" title="Enforcing happens-before through mutual exclusion">Enforcing <span class="emphasis"><em>happens-before</em></span>
through mutual exclusion</a>
</h3></div></div></div>
<p>
As an introductory example to understand how arguing using <span class="emphasis"><em>happens-before</em></span>
works, consider two threads synchronizing using a common mutex:
</p>
<pre class="programlisting"><span class="identifier">mutex</span> <span class="identifier">m</span><span class="special">;</span>
<span class="identifier">thread1</span><span class="special">:</span>
<span class="identifier">m</span><span class="special">.</span><span class="identifier">lock</span><span class="special">();</span>
<span class="special">...</span> <span class="comment">/* A */</span>
<span class="identifier">m</span><span class="special">.</span><span class="identifier">unlock</span><span class="special">();</span>
<span class="identifier">thread2</span><span class="special">:</span>
<span class="identifier">m</span><span class="special">.</span><span class="identifier">lock</span><span class="special">();</span>
<span class="special">...</span> <span class="comment">/* B */</span>
<span class="identifier">m</span><span class="special">.</span><span class="identifier">unlock</span><span class="special">();</span>
</pre>
<p>
The "lockset-based intuition" would be to argue that A and B cannot
be executed concurrently as the code paths require a common lock to be held.
</p>
<p>
One can however also arrive at the same conclusion using <span class="emphasis"><em>happens-before</em></span>:
Either thread1 or thread2 will succeed first at <code class="literal">m.lock()</code>.
If this is be thread1, then as a consequence, thread2 cannot succeed at
<code class="literal">m.lock()</code> before thread1 has executed <code class="literal">m.unlock()</code>,
consequently A <span class="emphasis"><em>happens-before</em></span> B in this case. By symmetry,
if thread2 succeeds at <code class="literal">m.lock()</code> first, we can conclude
B <span class="emphasis"><em>happens-before</em></span> A.
</p>
<p>
Since this already exhausts all options, we can conclude that either A <span class="emphasis"><em>happens-before</em></span>
B or B <span class="emphasis"><em>happens-before</em></span> A must always hold. Obviously
cannot state <span class="emphasis"><em>which</em></span> of the two relationships holds, but
either one is sufficient to conclude that A and B cannot conflict.
</p>
<p>
Compare the <a class="link" href="usage_examples.html#boost_atomic.usage_examples.example_spinlock" title="Spinlock">spinlock</a>
implementation to see how the mutual exclusion concept can be mapped to
<span class="bold"><strong>Boost.Atomic</strong></span>.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="atomic.thread_coordination.release_acquire"></a><a class="link" href="thread_coordination.html#atomic.thread_coordination.release_acquire" title="happens-before through release and acquire"><span class="emphasis"><em>happens-before</em></span>
through <code class="literal">release</code> and <code class="literal">acquire</code></a>
</h3></div></div></div>
<p>
The most basic pattern for coordinating threads via <span class="bold"><strong>Boost.Atomic</strong></span>
uses <code class="literal">release</code> and <code class="literal">acquire</code> on an atomic
variable for coordination: If ...
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
... thread1 performs an operation A,
</li>
<li class="listitem">
... thread1 subsequently writes (or atomically modifies) an atomic variable
with <code class="literal">release</code> semantic,
</li>
<li class="listitem">
... thread2 reads (or atomically reads-and-modifies) the value this value
from the same atomic variable with <code class="literal">acquire</code> semantic
and
</li>
<li class="listitem">
... thread2 subsequently performs an operation B,
</li>
</ul></div>
<p>
... then A <span class="emphasis"><em>happens-before</em></span> B.
</p>
<p>
Consider the following example
</p>
<pre class="programlisting"><span class="identifier">atomic</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">a</span><span class="special">(</span><span class="number">0</span><span class="special">);</span>
<span class="identifier">thread1</span><span class="special">:</span>
<span class="special">...</span> <span class="comment">/* A */</span>
<span class="identifier">a</span><span class="special">.</span><span class="identifier">fetch_add</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="identifier">memory_order_release</span><span class="special">);</span>
<span class="identifier">thread2</span><span class="special">:</span>
<span class="keyword">int</span> <span class="identifier">tmp</span> <span class="special">=</span> <span class="identifier">a</span><span class="special">.</span><span class="identifier">load</span><span class="special">(</span><span class="identifier">memory_order_acquire</span><span class="special">);</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">tmp</span> <span class="special">==</span> <span class="number">1</span><span class="special">)</span> <span class="special">{</span>
<span class="special">...</span> <span class="comment">/* B */</span>
<span class="special">}</span> <span class="keyword">else</span> <span class="special">{</span>
<span class="special">...</span> <span class="comment">/* C */</span>
<span class="special">}</span>
</pre>
<p>
In this example, two avenues for execution are possible:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
The <code class="literal">store</code> operation by thread1 precedes the <code class="literal">load</code>
by thread2: In this case thread2 will execute B and "A <span class="emphasis"><em>happens-before</em></span>
B" holds as all of the criteria above are satisfied.
</li>
<li class="listitem">
The <code class="literal">load</code> operation by thread2 precedes the <code class="literal">store</code>
by thread1: In this case, thread2 will execute C, but "A <span class="emphasis"><em>happens-before</em></span>
C" does <span class="emphasis"><em>not</em></span> hold: thread2 does not read the
value written by thread1 through <code class="literal">a</code>.
</li>
</ul></div>
<p>
Therefore, A and B cannot conflict, but A and C <span class="emphasis"><em>can</em></span>
conflict.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="atomic.thread_coordination.fences"></a><a class="link" href="thread_coordination.html#atomic.thread_coordination.fences" title="Fences">Fences</a>
</h3></div></div></div>
<p>
Ordering constraints are generally specified together with an access to an
atomic variable. It is however also possible to issue "fence" operations
in isolation, in this case the fence operates in conjunction with preceding
(for <code class="computeroutput"><span class="identifier">acquire</span></code>, <code class="computeroutput"><span class="identifier">consume</span></code> or <code class="computeroutput"><span class="identifier">seq_cst</span></code>
operations) or succeeding (for <code class="computeroutput"><span class="identifier">release</span></code>
or <code class="computeroutput"><span class="identifier">seq_cst</span></code>) atomic operations.
</p>
<p>
The example from the previous section could also be written in the following
way:
</p>
<pre class="programlisting"><span class="identifier">atomic</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">a</span><span class="special">(</span><span class="number">0</span><span class="special">);</span>
<span class="identifier">thread1</span><span class="special">:</span>
<span class="special">...</span> <span class="comment">/* A */</span>
<span class="identifier">atomic_thread_fence</span><span class="special">(</span><span class="identifier">memory_order_release</span><span class="special">);</span>
<span class="identifier">a</span><span class="special">.</span><span class="identifier">fetch_add</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="identifier">memory_order_relaxed</span><span class="special">);</span>
<span class="identifier">thread2</span><span class="special">:</span>
<span class="keyword">int</span> <span class="identifier">tmp</span> <span class="special">=</span> <span class="identifier">a</span><span class="special">.</span><span class="identifier">load</span><span class="special">(</span><span class="identifier">memory_order_relaxed</span><span class="special">);</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">tmp</span> <span class="special">==</span> <span class="number">1</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">atomic_thread_fence</span><span class="special">(</span><span class="identifier">memory_order_acquire</span><span class="special">);</span>
<span class="special">...</span> <span class="comment">/* B */</span>
<span class="special">}</span> <span class="keyword">else</span> <span class="special">{</span>
<span class="special">...</span> <span class="comment">/* C */</span>
<span class="special">}</span>
</pre>
<p>
This provides the same ordering guarantees as previously, but elides a (possibly
expensive) memory ordering operation in the case C is executed.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
Atomic fences are only indended to constraint ordering of regular and atomic
loads and stores for the purpose of thread synchronization. <code class="computeroutput"><span class="identifier">atomic_thread_fence</span></code> is not intended to
be used to order some architecture-specific memory accesses, such as non-temporal
loads and stores on x86 or write combining memory accesses. Use specialized
instructions for these purposes.
</p></td></tr>
</table></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="atomic.thread_coordination.release_consume"></a><a class="link" href="thread_coordination.html#atomic.thread_coordination.release_consume" title="happens-before through release and consume"><span class="emphasis"><em>happens-before</em></span>
through <code class="literal">release</code> and <code class="literal">consume</code></a>
</h3></div></div></div>
<p>
The second pattern for coordinating threads via <span class="bold"><strong>Boost.Atomic</strong></span>
uses <code class="literal">release</code> and <code class="literal">consume</code> on an atomic
variable for coordination: If ...
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
... thread1 performs an operation A,
</li>
<li class="listitem">
... thread1 subsequently writes (or atomically modifies) an atomic variable
with <code class="literal">release</code> semantic,
</li>
<li class="listitem">
... thread2 reads (or atomically reads-and-modifies) the value this value
from the same atomic variable with <code class="literal">consume</code> semantic
and
</li>
<li class="listitem">
... thread2 subsequently performs an operation B that is <span class="emphasis"><em>computationally
dependent on the value of the atomic variable</em></span>,
</li>
</ul></div>
<p>
... then A <span class="emphasis"><em>happens-before</em></span> B.
</p>
<p>
Consider the following example
</p>
<pre class="programlisting"><span class="identifier">atomic</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">a</span><span class="special">(</span><span class="number">0</span><span class="special">);</span>
<span class="identifier">complex_data_structure</span> <span class="identifier">data</span><span class="special">[</span><span class="number">2</span><span class="special">];</span>
<span class="identifier">thread1</span><span class="special">:</span>
<span class="identifier">data</span><span class="special">[</span><span class="number">1</span><span class="special">]</span> <span class="special">=</span> <span class="special">...;</span> <span class="comment">/* A */</span>
<span class="identifier">a</span><span class="special">.</span><span class="identifier">store</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="identifier">memory_order_release</span><span class="special">);</span>
<span class="identifier">thread2</span><span class="special">:</span>
<span class="keyword">int</span> <span class="identifier">index</span> <span class="special">=</span> <span class="identifier">a</span><span class="special">.</span><span class="identifier">load</span><span class="special">(</span><span class="identifier">memory_order_consume</span><span class="special">);</span>
<span class="identifier">complex_data_structure</span> <span class="identifier">tmp</span> <span class="special">=</span> <span class="identifier">data</span><span class="special">[</span><span class="identifier">index</span><span class="special">];</span> <span class="comment">/* B */</span>
</pre>
<p>
In this example, two avenues for execution are possible:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
The <code class="literal">store</code> operation by thread1 precedes the <code class="literal">load</code>
by thread2: In this case thread2 will read <code class="literal">data[1]</code>
and "A <span class="emphasis"><em>happens-before</em></span> B" holds as all
of the criteria above are satisfied.
</li>
<li class="listitem">
The <code class="literal">load</code> operation by thread2 precedes the <code class="literal">store</code>
by thread1: In this case thread2 will read <code class="literal">data[0]</code>
and "A <span class="emphasis"><em>happens-before</em></span> B" does <span class="emphasis"><em>not</em></span>
hold: thread2 does not read the value written by thread1 through <code class="literal">a</code>.
</li>
</ul></div>
<p>
Here, the <span class="emphasis"><em>happens-before</em></span> relationship helps ensure that
any accesses (presumable writes) to <code class="literal">data[1]</code> by thread1
happen before before the accesses (presumably reads) to <code class="literal">data[1]</code>
by thread2: Lacking this relationship, thread2 might see stale/inconsistent
data.
</p>
<p>
Note that in this example, the fact that operation B is computationally dependent
on the atomic variable, therefore the following program would be erroneous:
</p>
<pre class="programlisting"><span class="identifier">atomic</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">a</span><span class="special">(</span><span class="number">0</span><span class="special">);</span>
<span class="identifier">complex_data_structure</span> <span class="identifier">data</span><span class="special">[</span><span class="number">2</span><span class="special">];</span>
<span class="identifier">thread1</span><span class="special">:</span>
<span class="identifier">data</span><span class="special">[</span><span class="number">1</span><span class="special">]</span> <span class="special">=</span> <span class="special">...;</span> <span class="comment">/* A */</span>
<span class="identifier">a</span><span class="special">.</span><span class="identifier">store</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="identifier">memory_order_release</span><span class="special">);</span>
<span class="identifier">thread2</span><span class="special">:</span>
<span class="keyword">int</span> <span class="identifier">index</span> <span class="special">=</span> <span class="identifier">a</span><span class="special">.</span><span class="identifier">load</span><span class="special">(</span><span class="identifier">memory_order_consume</span><span class="special">);</span>
<span class="identifier">complex_data_structure</span> <span class="identifier">tmp</span><span class="special">;</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">index</span> <span class="special">==</span> <span class="number">0</span><span class="special">)</span>
<span class="identifier">tmp</span> <span class="special">=</span> <span class="identifier">data</span><span class="special">[</span><span class="number">0</span><span class="special">];</span>
<span class="keyword">else</span>
<span class="identifier">tmp</span> <span class="special">=</span> <span class="identifier">data</span><span class="special">[</span><span class="number">1</span><span class="special">];</span>
</pre>
<p>
<code class="literal">consume</code> is most commonly (and most safely! see <a class="link" href="limitations.html" title="Limitations">limitations</a>)
used with pointers, compare for example the <a class="link" href="usage_examples.html#boost_atomic.usage_examples.singleton" title="Singleton with double-checked locking pattern">singleton
with double-checked locking</a>.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="atomic.thread_coordination.seq_cst"></a><a class="link" href="thread_coordination.html#atomic.thread_coordination.seq_cst" title="Sequential consistency">Sequential consistency</a>
</h3></div></div></div>
<p>
The third pattern for coordinating threads via <span class="bold"><strong>Boost.Atomic</strong></span>
uses <code class="literal">seq_cst</code> for coordination: If ...
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
... thread1 performs an operation A,
</li>
<li class="listitem">
... thread1 subsequently performs any operation with <code class="literal">seq_cst</code>,
</li>
<li class="listitem">
... thread1 subsequently performs an operation B,
</li>
<li class="listitem">
... thread2 performs an operation C,
</li>
<li class="listitem">
... thread2 subsequently performs any operation with <code class="literal">seq_cst</code>,
</li>
<li class="listitem">
... thread2 subsequently performs an operation D,
</li>
</ul></div>
<p>
then either "A <span class="emphasis"><em>happens-before</em></span> D" or "C
<span class="emphasis"><em>happens-before</em></span> B" holds.
</p>
<p>
In this case it does not matter whether thread1 and thread2 operate on the
same or different atomic variables, or use a "stand-alone" <code class="literal">atomic_thread_fence</code>
operation.
</p>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2011 Helge Bahmann<br>Copyright © 2012 Tim Blechmann<br>Copyright © 2013, 2017, 2018, 2020 Andrey
Semashev<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../atomic.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../atomic.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="interface.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,489 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Usage examples</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../atomic.html" title="Chapter 6. Boost.Atomic">
<link rel="prev" href="interface.html" title="Programming interfaces">
<link rel="next" href="limitations.html" title="Limitations">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="interface.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../atomic.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="limitations.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="atomic.usage_examples"></a><a class="link" href="usage_examples.html" title="Usage examples">Usage examples</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="usage_examples.html#boost_atomic.usage_examples.example_reference_counters">Reference
counting</a></span></dt>
<dt><span class="section"><a href="usage_examples.html#boost_atomic.usage_examples.example_spinlock">Spinlock</a></span></dt>
<dt><span class="section"><a href="usage_examples.html#boost_atomic.usage_examples.singleton">Singleton with
double-checked locking pattern</a></span></dt>
<dt><span class="section"><a href="usage_examples.html#boost_atomic.usage_examples.example_ringbuffer">Wait-free
ring buffer</a></span></dt>
<dt><span class="section"><a href="usage_examples.html#boost_atomic.usage_examples.mp_queue">Lock-free multi-producer
queue</a></span></dt>
</dl></div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_atomic.usage_examples.example_reference_counters"></a><a class="link" href="usage_examples.html#boost_atomic.usage_examples.example_reference_counters" title="Reference counting">Reference
counting</a>
</h3></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="usage_examples.html#boost_atomic.usage_examples.example_reference_counters.implementation">Implementation</a></span></dt>
<dt><span class="section"><a href="usage_examples.html#boost_atomic.usage_examples.example_reference_counters.usage">Usage</a></span></dt>
<dt><span class="section"><a href="usage_examples.html#boost_atomic.usage_examples.example_reference_counters.discussion">Discussion</a></span></dt>
</dl></div>
<p>
The purpose of a <span class="emphasis"><em>reference counter</em></span> is to count the number
of pointers to an object. The object can be destroyed as soon as the reference
counter reaches zero.
</p>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_atomic.usage_examples.example_reference_counters.implementation"></a><a class="link" href="usage_examples.html#boost_atomic.usage_examples.example_reference_counters.implementation" title="Implementation">Implementation</a>
</h4></div></div></div>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">intrusive_ptr</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">atomic</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="keyword">class</span> <span class="identifier">X</span> <span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">intrusive_ptr</span><span class="special">&lt;</span><span class="identifier">X</span><span class="special">&gt;</span> <span class="identifier">pointer</span><span class="special">;</span>
<span class="identifier">X</span><span class="special">()</span> <span class="special">:</span> <span class="identifier">refcount_</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">{}</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="keyword">mutable</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">atomic</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">refcount_</span><span class="special">;</span>
<span class="keyword">friend</span> <span class="keyword">void</span> <span class="identifier">intrusive_ptr_add_ref</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">X</span> <span class="special">*</span> <span class="identifier">x</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">x</span><span class="special">-&gt;</span><span class="identifier">refcount_</span><span class="special">.</span><span class="identifier">fetch_add</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">memory_order_relaxed</span><span class="special">);</span>
<span class="special">}</span>
<span class="keyword">friend</span> <span class="keyword">void</span> <span class="identifier">intrusive_ptr_release</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">X</span> <span class="special">*</span> <span class="identifier">x</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">x</span><span class="special">-&gt;</span><span class="identifier">refcount_</span><span class="special">.</span><span class="identifier">fetch_sub</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">memory_order_release</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">atomic_thread_fence</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">memory_order_acquire</span><span class="special">);</span>
<span class="keyword">delete</span> <span class="identifier">x</span><span class="special">;</span>
<span class="special">}</span>
<span class="special">}</span>
<span class="special">};</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_atomic.usage_examples.example_reference_counters.usage"></a><a class="link" href="usage_examples.html#boost_atomic.usage_examples.example_reference_counters.usage" title="Usage">Usage</a>
</h4></div></div></div>
<pre class="programlisting"><span class="identifier">X</span><span class="special">::</span><span class="identifier">pointer</span> <span class="identifier">x</span> <span class="special">=</span> <span class="keyword">new</span> <span class="identifier">X</span><span class="special">;</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_atomic.usage_examples.example_reference_counters.discussion"></a><a class="link" href="usage_examples.html#boost_atomic.usage_examples.example_reference_counters.discussion" title="Discussion">Discussion</a>
</h4></div></div></div>
<p>
Increasing the reference counter can always be done with <code class="literal">memory_order_relaxed</code>:
New references to an object can only be formed from an existing reference,
and passing an existing reference from one thread to another must already
provide any required synchronization.
</p>
<p>
It is important to enforce any possible access to the object in one thread
(through an existing reference) to <span class="emphasis"><em>happen before</em></span> deleting
the object in a different thread. This is achieved by a "release"
operation after dropping a reference (any access to the object through
this reference must obviously happened before), and an "acquire"
operation before deleting the object.
</p>
<p>
It would be possible to use <code class="literal">memory_order_acq_rel</code> for
the <code class="literal">fetch_sub</code> operation, but this results in unneeded
"acquire" operations when the reference counter does not yet
reach zero and may impose a performance penalty.
</p>
</div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_atomic.usage_examples.example_spinlock"></a><a class="link" href="usage_examples.html#boost_atomic.usage_examples.example_spinlock" title="Spinlock">Spinlock</a>
</h3></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="usage_examples.html#boost_atomic.usage_examples.example_spinlock.implementation">Implementation</a></span></dt>
<dt><span class="section"><a href="usage_examples.html#boost_atomic.usage_examples.example_spinlock.usage">Usage</a></span></dt>
<dt><span class="section"><a href="usage_examples.html#boost_atomic.usage_examples.example_spinlock.discussion">Discussion</a></span></dt>
</dl></div>
<p>
The purpose of a <span class="emphasis"><em>spin lock</em></span> is to prevent multiple threads
from concurrently accessing a shared data structure. In contrast to a mutex,
threads will busy-wait and waste CPU cycles instead of yielding the CPU to
another thread. <span class="emphasis"><em>Do not use spinlocks unless you are certain that
you understand the consequences.</em></span>
</p>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_atomic.usage_examples.example_spinlock.implementation"></a><a class="link" href="usage_examples.html#boost_atomic.usage_examples.example_spinlock.implementation" title="Implementation">Implementation</a>
</h4></div></div></div>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">atomic</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="keyword">class</span> <span class="identifier">spinlock</span> <span class="special">{</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="keyword">typedef</span> <span class="keyword">enum</span> <span class="special">{</span><span class="identifier">Locked</span><span class="special">,</span> <span class="identifier">Unlocked</span><span class="special">}</span> <span class="identifier">LockState</span><span class="special">;</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">atomic</span><span class="special">&lt;</span><span class="identifier">LockState</span><span class="special">&gt;</span> <span class="identifier">state_</span><span class="special">;</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="identifier">spinlock</span><span class="special">()</span> <span class="special">:</span> <span class="identifier">state_</span><span class="special">(</span><span class="identifier">Unlocked</span><span class="special">)</span> <span class="special">{}</span>
<span class="keyword">void</span> <span class="identifier">lock</span><span class="special">()</span>
<span class="special">{</span>
<span class="keyword">while</span> <span class="special">(</span><span class="identifier">state_</span><span class="special">.</span><span class="identifier">exchange</span><span class="special">(</span><span class="identifier">Locked</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">memory_order_acquire</span><span class="special">)</span> <span class="special">==</span> <span class="identifier">Locked</span><span class="special">)</span> <span class="special">{</span>
<span class="comment">/* busy-wait */</span>
<span class="special">}</span>
<span class="special">}</span>
<span class="keyword">void</span> <span class="identifier">unlock</span><span class="special">()</span>
<span class="special">{</span>
<span class="identifier">state_</span><span class="special">.</span><span class="identifier">store</span><span class="special">(</span><span class="identifier">Unlocked</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">memory_order_release</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">};</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_atomic.usage_examples.example_spinlock.usage"></a><a class="link" href="usage_examples.html#boost_atomic.usage_examples.example_spinlock.usage" title="Usage">Usage</a>
</h4></div></div></div>
<pre class="programlisting"><span class="identifier">spinlock</span> <span class="identifier">s</span><span class="special">;</span>
<span class="identifier">s</span><span class="special">.</span><span class="identifier">lock</span><span class="special">();</span>
<span class="comment">// access data structure here</span>
<span class="identifier">s</span><span class="special">.</span><span class="identifier">unlock</span><span class="special">();</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_atomic.usage_examples.example_spinlock.discussion"></a><a class="link" href="usage_examples.html#boost_atomic.usage_examples.example_spinlock.discussion" title="Discussion">Discussion</a>
</h4></div></div></div>
<p>
The purpose of the spinlock is to make sure that one access to the shared
data structure always strictly "happens before" another. The
usage of acquire/release in lock/unlock is required and sufficient to guarantee
this ordering.
</p>
<p>
It would be correct to write the "lock" operation in the following
way:
</p>
<pre class="programlisting"><span class="identifier">lock</span><span class="special">()</span>
<span class="special">{</span>
<span class="keyword">while</span> <span class="special">(</span><span class="identifier">state_</span><span class="special">.</span><span class="identifier">exchange</span><span class="special">(</span><span class="identifier">Locked</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">memory_order_relaxed</span><span class="special">)</span> <span class="special">==</span> <span class="identifier">Locked</span><span class="special">)</span> <span class="special">{</span>
<span class="comment">/* busy-wait */</span>
<span class="special">}</span>
<span class="identifier">atomic_thread_fence</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">memory_order_acquire</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
This "optimization" is however a) useless and b) may in fact
hurt: a) Since the thread will be busily spinning on a blocked spinlock,
it does not matter if it will waste the CPU cycles with just "exchange"
operations or with both useless "exchange" and "acquire"
operations. b) A tight "exchange" loop without any memory-synchronizing
instruction introduced through an "acquire" operation will on
some systems monopolize the memory subsystem and degrade the performance
of other system components.
</p>
</div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_atomic.usage_examples.singleton"></a><a class="link" href="usage_examples.html#boost_atomic.usage_examples.singleton" title="Singleton with double-checked locking pattern">Singleton with
double-checked locking pattern</a>
</h3></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="usage_examples.html#boost_atomic.usage_examples.singleton.implementation">Implementation</a></span></dt>
<dt><span class="section"><a href="usage_examples.html#boost_atomic.usage_examples.singleton.usage">Usage</a></span></dt>
<dt><span class="section"><a href="usage_examples.html#boost_atomic.usage_examples.singleton.discussion">Discussion</a></span></dt>
</dl></div>
<p>
The purpose of the <span class="emphasis"><em>Singleton with double-checked locking pattern</em></span>
is to ensure that at most one instance of a particular object is created.
If one instance has been created already, access to the existing object should
be as light-weight as possible.
</p>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_atomic.usage_examples.singleton.implementation"></a><a class="link" href="usage_examples.html#boost_atomic.usage_examples.singleton.implementation" title="Implementation">Implementation</a>
</h4></div></div></div>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">atomic</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">thread</span><span class="special">/</span><span class="identifier">mutex</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="keyword">class</span> <span class="identifier">X</span> <span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="keyword">static</span> <span class="identifier">X</span> <span class="special">*</span> <span class="identifier">instance</span><span class="special">()</span>
<span class="special">{</span>
<span class="identifier">X</span> <span class="special">*</span> <span class="identifier">tmp</span> <span class="special">=</span> <span class="identifier">instance_</span><span class="special">.</span><span class="identifier">load</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">memory_order_consume</span><span class="special">);</span>
<span class="keyword">if</span> <span class="special">(!</span><span class="identifier">tmp</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">mutex</span><span class="special">::</span><span class="identifier">scoped_lock</span> <span class="identifier">guard</span><span class="special">(</span><span class="identifier">instantiation_mutex</span><span class="special">);</span>
<span class="identifier">tmp</span> <span class="special">=</span> <span class="identifier">instance_</span><span class="special">.</span><span class="identifier">load</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">memory_order_consume</span><span class="special">);</span>
<span class="keyword">if</span> <span class="special">(!</span><span class="identifier">tmp</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">tmp</span> <span class="special">=</span> <span class="keyword">new</span> <span class="identifier">X</span><span class="special">;</span>
<span class="identifier">instance_</span><span class="special">.</span><span class="identifier">store</span><span class="special">(</span><span class="identifier">tmp</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">memory_order_release</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">}</span>
<span class="keyword">return</span> <span class="identifier">tmp</span><span class="special">;</span>
<span class="special">}</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="keyword">static</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">atomic</span><span class="special">&lt;</span><span class="identifier">X</span> <span class="special">*&gt;</span> <span class="identifier">instance_</span><span class="special">;</span>
<span class="keyword">static</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">mutex</span> <span class="identifier">instantiation_mutex</span><span class="special">;</span>
<span class="special">};</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">atomic</span><span class="special">&lt;</span><span class="identifier">X</span> <span class="special">*&gt;</span> <span class="identifier">X</span><span class="special">::</span><span class="identifier">instance_</span><span class="special">(</span><span class="number">0</span><span class="special">);</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_atomic.usage_examples.singleton.usage"></a><a class="link" href="usage_examples.html#boost_atomic.usage_examples.singleton.usage" title="Usage">Usage</a>
</h4></div></div></div>
<pre class="programlisting"><span class="identifier">X</span> <span class="special">*</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">X</span><span class="special">::</span><span class="identifier">instance</span><span class="special">();</span>
<span class="comment">// dereference x</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_atomic.usage_examples.singleton.discussion"></a><a class="link" href="usage_examples.html#boost_atomic.usage_examples.singleton.discussion" title="Discussion">Discussion</a>
</h4></div></div></div>
<p>
The mutex makes sure that only one instance of the object is ever created.
The <code class="literal">instance</code> method must make sure that any dereference
of the object strictly "happens after" creating the instance
in another thread. The use of <code class="literal">memory_order_release</code> after
creating and initializing the object and <code class="literal">memory_order_consume</code>
before dereferencing the object provides this guarantee.
</p>
<p>
It would be permissible to use <code class="literal">memory_order_acquire</code>
instead of <code class="literal">memory_order_consume</code>, but this provides a
stronger guarantee than is required since only operations depending on
the value of the pointer need to be ordered.
</p>
</div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_atomic.usage_examples.example_ringbuffer"></a><a class="link" href="usage_examples.html#boost_atomic.usage_examples.example_ringbuffer" title="Wait-free ring buffer">Wait-free
ring buffer</a>
</h3></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="usage_examples.html#boost_atomic.usage_examples.example_ringbuffer.implementation">Implementation</a></span></dt>
<dt><span class="section"><a href="usage_examples.html#boost_atomic.usage_examples.example_ringbuffer.usage">Usage</a></span></dt>
<dt><span class="section"><a href="usage_examples.html#boost_atomic.usage_examples.example_ringbuffer.discussion">Discussion</a></span></dt>
</dl></div>
<p>
A <span class="emphasis"><em>wait-free ring buffer</em></span> provides a mechanism for relaying
objects from one single "producer" thread to one single "consumer"
thread without any locks. The operations on this data structure are "wait-free"
which means that each operation finishes within a constant number of steps.
This makes this data structure suitable for use in hard real-time systems
or for communication with interrupt/signal handlers.
</p>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_atomic.usage_examples.example_ringbuffer.implementation"></a><a class="link" href="usage_examples.html#boost_atomic.usage_examples.example_ringbuffer.implementation" title="Implementation">Implementation</a>
</h4></div></div></div>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">atomic</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span> <span class="identifier">size_t</span> <span class="identifier">Size</span><span class="special">&gt;</span>
<span class="keyword">class</span> <span class="identifier">ringbuffer</span> <span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="identifier">ringbuffer</span><span class="special">()</span> <span class="special">:</span> <span class="identifier">head_</span><span class="special">(</span><span class="number">0</span><span class="special">),</span> <span class="identifier">tail_</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">{}</span>
<span class="keyword">bool</span> <span class="identifier">push</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span> <span class="special">&amp;</span> <span class="identifier">value</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">size_t</span> <span class="identifier">head</span> <span class="special">=</span> <span class="identifier">head_</span><span class="special">.</span><span class="identifier">load</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">memory_order_relaxed</span><span class="special">);</span>
<span class="identifier">size_t</span> <span class="identifier">next_head</span> <span class="special">=</span> <span class="identifier">next</span><span class="special">(</span><span class="identifier">head</span><span class="special">);</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">next_head</span> <span class="special">==</span> <span class="identifier">tail_</span><span class="special">.</span><span class="identifier">load</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">memory_order_acquire</span><span class="special">))</span>
<span class="keyword">return</span> <span class="keyword">false</span><span class="special">;</span>
<span class="identifier">ring_</span><span class="special">[</span><span class="identifier">head</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">value</span><span class="special">;</span>
<span class="identifier">head_</span><span class="special">.</span><span class="identifier">store</span><span class="special">(</span><span class="identifier">next_head</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">memory_order_release</span><span class="special">);</span>
<span class="keyword">return</span> <span class="keyword">true</span><span class="special">;</span>
<span class="special">}</span>
<span class="keyword">bool</span> <span class="identifier">pop</span><span class="special">(</span><span class="identifier">T</span> <span class="special">&amp;</span> <span class="identifier">value</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">size_t</span> <span class="identifier">tail</span> <span class="special">=</span> <span class="identifier">tail_</span><span class="special">.</span><span class="identifier">load</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">memory_order_relaxed</span><span class="special">);</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">tail</span> <span class="special">==</span> <span class="identifier">head_</span><span class="special">.</span><span class="identifier">load</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">memory_order_acquire</span><span class="special">))</span>
<span class="keyword">return</span> <span class="keyword">false</span><span class="special">;</span>
<span class="identifier">value</span> <span class="special">=</span> <span class="identifier">ring_</span><span class="special">[</span><span class="identifier">tail</span><span class="special">];</span>
<span class="identifier">tail_</span><span class="special">.</span><span class="identifier">store</span><span class="special">(</span><span class="identifier">next</span><span class="special">(</span><span class="identifier">tail</span><span class="special">),</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">memory_order_release</span><span class="special">);</span>
<span class="keyword">return</span> <span class="keyword">true</span><span class="special">;</span>
<span class="special">}</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="identifier">size_t</span> <span class="identifier">next</span><span class="special">(</span><span class="identifier">size_t</span> <span class="identifier">current</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="special">(</span><span class="identifier">current</span> <span class="special">+</span> <span class="number">1</span><span class="special">)</span> <span class="special">%</span> <span class="identifier">Size</span><span class="special">;</span>
<span class="special">}</span>
<span class="identifier">T</span> <span class="identifier">ring_</span><span class="special">[</span><span class="identifier">Size</span><span class="special">];</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">atomic</span><span class="special">&lt;</span><span class="identifier">size_t</span><span class="special">&gt;</span> <span class="identifier">head_</span><span class="special">,</span> <span class="identifier">tail_</span><span class="special">;</span>
<span class="special">};</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_atomic.usage_examples.example_ringbuffer.usage"></a><a class="link" href="usage_examples.html#boost_atomic.usage_examples.example_ringbuffer.usage" title="Usage">Usage</a>
</h4></div></div></div>
<pre class="programlisting"><span class="identifier">ringbuffer</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="number">32</span><span class="special">&gt;</span> <span class="identifier">r</span><span class="special">;</span>
<span class="comment">// try to insert an element</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">push</span><span class="special">(</span><span class="number">42</span><span class="special">))</span> <span class="special">{</span> <span class="comment">/* succeeded */</span> <span class="special">}</span>
<span class="keyword">else</span> <span class="special">{</span> <span class="comment">/* buffer full */</span> <span class="special">}</span>
<span class="comment">// try to retrieve an element</span>
<span class="keyword">int</span> <span class="identifier">value</span><span class="special">;</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">pop</span><span class="special">(</span><span class="identifier">value</span><span class="special">))</span> <span class="special">{</span> <span class="comment">/* succeeded */</span> <span class="special">}</span>
<span class="keyword">else</span> <span class="special">{</span> <span class="comment">/* buffer empty */</span> <span class="special">}</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_atomic.usage_examples.example_ringbuffer.discussion"></a><a class="link" href="usage_examples.html#boost_atomic.usage_examples.example_ringbuffer.discussion" title="Discussion">Discussion</a>
</h4></div></div></div>
<p>
The implementation makes sure that the ring indices do not "lap-around"
each other to ensure that no elements are either lost or read twice.
</p>
<p>
Furthermore it must guarantee that read-access to a particular object in
<code class="literal">pop</code> "happens after" it has been written in
<code class="literal">push</code>. This is achieved by writing <code class="literal">head_ </code>
with "release" and reading it with "acquire". Conversely
the implementation also ensures that read access to a particular ring element
"happens before" before rewriting this element with a new value
by accessing <code class="literal">tail_</code> with appropriate ordering constraints.
</p>
</div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_atomic.usage_examples.mp_queue"></a><a class="link" href="usage_examples.html#boost_atomic.usage_examples.mp_queue" title="Lock-free multi-producer queue">Lock-free multi-producer
queue</a>
</h3></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="usage_examples.html#boost_atomic.usage_examples.mp_queue.implementation">Implementation</a></span></dt>
<dt><span class="section"><a href="usage_examples.html#boost_atomic.usage_examples.mp_queue.usage">Usage</a></span></dt>
<dt><span class="section"><a href="usage_examples.html#boost_atomic.usage_examples.mp_queue.discussion">Discussion</a></span></dt>
</dl></div>
<p>
The purpose of the <span class="emphasis"><em>lock-free multi-producer queue</em></span> is
to allow an arbitrary number of producers to enqueue objects which are retrieved
and processed in FIFO order by a single consumer.
</p>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_atomic.usage_examples.mp_queue.implementation"></a><a class="link" href="usage_examples.html#boost_atomic.usage_examples.mp_queue.implementation" title="Implementation">Implementation</a>
</h4></div></div></div>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="keyword">class</span> <span class="identifier">lockfree_queue</span> <span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="keyword">struct</span> <span class="identifier">node</span> <span class="special">{</span>
<span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span>
<span class="identifier">node</span> <span class="special">*</span> <span class="identifier">next</span><span class="special">;</span>
<span class="special">};</span>
<span class="keyword">void</span> <span class="identifier">push</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span> <span class="special">&amp;</span><span class="identifier">data</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">node</span> <span class="special">*</span> <span class="identifier">n</span> <span class="special">=</span> <span class="keyword">new</span> <span class="identifier">node</span><span class="special">;</span>
<span class="identifier">n</span><span class="special">-&gt;</span><span class="identifier">data</span> <span class="special">=</span> <span class="identifier">data</span><span class="special">;</span>
<span class="identifier">node</span> <span class="special">*</span> <span class="identifier">stale_head</span> <span class="special">=</span> <span class="identifier">head_</span><span class="special">.</span><span class="identifier">load</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">memory_order_relaxed</span><span class="special">);</span>
<span class="keyword">do</span> <span class="special">{</span>
<span class="identifier">n</span><span class="special">-&gt;</span><span class="identifier">next</span> <span class="special">=</span> <span class="identifier">stale_head</span><span class="special">;</span>
<span class="special">}</span> <span class="keyword">while</span> <span class="special">(!</span><span class="identifier">head_</span><span class="special">.</span><span class="identifier">compare_exchange_weak</span><span class="special">(</span><span class="identifier">stale_head</span><span class="special">,</span> <span class="identifier">n</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">memory_order_release</span><span class="special">));</span>
<span class="special">}</span>
<span class="identifier">node</span> <span class="special">*</span> <span class="identifier">pop_all</span><span class="special">(</span><span class="keyword">void</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">T</span> <span class="special">*</span> <span class="identifier">last</span> <span class="special">=</span> <span class="identifier">pop_all_reverse</span><span class="special">(),</span> <span class="special">*</span> <span class="identifier">first</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
<span class="keyword">while</span><span class="special">(</span><span class="identifier">last</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">T</span> <span class="special">*</span> <span class="identifier">tmp</span> <span class="special">=</span> <span class="identifier">last</span><span class="special">;</span>
<span class="identifier">last</span> <span class="special">=</span> <span class="identifier">last</span><span class="special">-&gt;</span><span class="identifier">next</span><span class="special">;</span>
<span class="identifier">tmp</span><span class="special">-&gt;</span><span class="identifier">next</span> <span class="special">=</span> <span class="identifier">first</span><span class="special">;</span>
<span class="identifier">first</span> <span class="special">=</span> <span class="identifier">tmp</span><span class="special">;</span>
<span class="special">}</span>
<span class="keyword">return</span> <span class="identifier">first</span><span class="special">;</span>
<span class="special">}</span>
<span class="identifier">lockfree_queue</span><span class="special">()</span> <span class="special">:</span> <span class="identifier">head_</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">{}</span>
<span class="comment">// alternative interface if ordering is of no importance</span>
<span class="identifier">node</span> <span class="special">*</span> <span class="identifier">pop_all_reverse</span><span class="special">(</span><span class="keyword">void</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">head_</span><span class="special">.</span><span class="identifier">exchange</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">memory_order_consume</span><span class="special">);</span>
<span class="special">}</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">atomic</span><span class="special">&lt;</span><span class="identifier">node</span> <span class="special">*&gt;</span> <span class="identifier">head_</span><span class="special">;</span>
<span class="special">};</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_atomic.usage_examples.mp_queue.usage"></a><a class="link" href="usage_examples.html#boost_atomic.usage_examples.mp_queue.usage" title="Usage">Usage</a>
</h4></div></div></div>
<pre class="programlisting"><span class="identifier">lockfree_queue</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">q</span><span class="special">;</span>
<span class="comment">// insert elements</span>
<span class="identifier">q</span><span class="special">.</span><span class="identifier">push</span><span class="special">(</span><span class="number">42</span><span class="special">);</span>
<span class="identifier">q</span><span class="special">.</span><span class="identifier">push</span><span class="special">(</span><span class="number">2</span><span class="special">);</span>
<span class="comment">// pop elements</span>
<span class="identifier">lockfree_queue</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;::</span><span class="identifier">node</span> <span class="special">*</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">q</span><span class="special">.</span><span class="identifier">pop_all</span><span class="special">()</span>
<span class="keyword">while</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">X</span> <span class="special">*</span> <span class="identifier">tmp</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">;</span>
<span class="identifier">x</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">-&gt;</span><span class="identifier">next</span><span class="special">;</span>
<span class="comment">// process tmp-&gt;data, probably delete it afterwards</span>
<span class="keyword">delete</span> <span class="identifier">tmp</span><span class="special">;</span>
<span class="special">}</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_atomic.usage_examples.mp_queue.discussion"></a><a class="link" href="usage_examples.html#boost_atomic.usage_examples.mp_queue.discussion" title="Discussion">Discussion</a>
</h4></div></div></div>
<p>
The implementation guarantees that all objects enqueued are processed in
the order they were enqueued by building a singly-linked list of object
in reverse processing order. The queue is atomically emptied by the consumer
(in an operation that is not only lock-free but wait-free) and brought
into correct order.
</p>
<p>
It must be guaranteed that any access to an object to be enqueued by the
producer "happens before" any access by the consumer. This is
assured by inserting objects into the list with <span class="emphasis"><em>release</em></span>
and dequeuing them with <span class="emphasis"><em>consume</em></span> memory order. It is
not necessary to use <span class="emphasis"><em>acquire</em></span> memory order in <code class="literal">waitfree_queue::pop_all</code>
because all operations involved depend on the value of the atomic pointer
through dereference.
</p>
</div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2011 Helge Bahmann<br>Copyright © 2012 Tim Blechmann<br>Copyright © 2013, 2017, 2018, 2020 Andrey
Semashev<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="interface.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../atomic.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="limitations.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>