mirror of git://gcc.gnu.org/git/gcc.git
343 lines
9.4 KiB
HTML
343 lines
9.4 KiB
HTML
<?xml version="1.0" encoding="ISO-8859-1"?>
|
|
<!DOCTYPE html
|
|
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
|
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
|
<head>
|
|
<meta name="AUTHOR" content="bkoz@gcc.gnu.org (Benjamin Kosnik)" />
|
|
<meta name="KEYWORDS" content="C++, libstdc++, MT, thread, pthread, mutex, loc, atomic" />
|
|
<meta name="DESCRIPTION" content="Concurrency Support" />
|
|
<meta name="GENERATOR" content="emacs and ten fingers" />
|
|
<title>Concurrency Support</title>
|
|
<link rel="StyleSheet" href="lib3styles.css" type="text/css" />
|
|
<link rel="Start" href="documentation.html" type="text/html"
|
|
title="GNU C++ Standard Library" />
|
|
<link rel="Copyright" href="17_intro/license.html" type="text/html" />
|
|
</head>
|
|
<body>
|
|
|
|
<h1 class="centered"><a name="top">Concurrency Support</a></h1>
|
|
|
|
<p class="fineprint"><em>
|
|
The latest version of this document is always available at
|
|
<a href="http://gcc.gnu.org/onlinedocs/libstdc++/17_intro/concurrence.html">
|
|
http://gcc.gnu.org/onlinedocs/libstdc++/17_intro/concurrence.html</a>.
|
|
</em></p>
|
|
|
|
<p><em>
|
|
To the <a href="http://gcc.gnu.org/libstdc++/">libstdc++ homepage</a>.
|
|
</em></p>
|
|
|
|
|
|
<!-- ####################################################### -->
|
|
|
|
<hr />
|
|
|
|
|
|
<p>The interface for concurrency support is divided into two files:
|
|
<ext/atomicity.h> which provides support for atomic operations,
|
|
and <ext/concurrence.h>, which provides mutex and lock objects
|
|
as well as compile-time data structures for querying thread
|
|
support.</p>
|
|
|
|
<p>It is expected that support for concurrence will evolve into what
|
|
is specified in the draft C++0x standard.</p>
|
|
|
|
<h3 class="left">
|
|
<a name="atomic_api">Atomics Interface</a>
|
|
</h3>
|
|
|
|
<p>
|
|
Two functions and one type form the base of atomic support.
|
|
</p>
|
|
|
|
|
|
<p>The type <code>_Atomic_word</code> is a signed integral type
|
|
supporting atomic operations.
|
|
</p>
|
|
|
|
<p>
|
|
The two functions functions are:
|
|
</p>
|
|
|
|
<pre>
|
|
_Atomic_word
|
|
__exchange_and_add_dispatch(volatile _Atomic_word*, int);
|
|
|
|
void
|
|
__atomic_add_dispatch(volatile _Atomic_word*, int);
|
|
</pre>
|
|
|
|
<p>Both of these functions are declared in the header file
|
|
<ext/atomicity.h>, and are in <code>namespace __gnu_cxx</code>.
|
|
</p>
|
|
|
|
<ul>
|
|
<li>
|
|
<code>
|
|
__exchange_and_add_dispatch
|
|
</code>
|
|
<p>Adds the second argument's value to the first argument. Returns the old value.
|
|
</p>
|
|
</li>
|
|
<li>
|
|
<code>
|
|
__atomic_add_dispatch
|
|
</code>
|
|
<p>Adds the second argument's value to the first argument. Has no return value.
|
|
</p>
|
|
</li>
|
|
</ul>
|
|
|
|
<p>
|
|
These functions forward to one of several specialized helper
|
|
functions, depending on the circumstances. For instance,
|
|
</p>
|
|
|
|
<p>
|
|
<code>
|
|
__exchange_and_add_dispatch
|
|
</code>
|
|
</p>
|
|
|
|
<p>
|
|
Calls through to either of:
|
|
</p>
|
|
|
|
<ul>
|
|
<li><code>__exchange_and_add</code>
|
|
<p>Multi-thread version. Inlined if compiler-generated builtin atomics
|
|
can be used, otherwise resolved at link time to a non-builtin code
|
|
sequence.
|
|
</p>
|
|
</li>
|
|
|
|
<li><code>__exchange_and_add_single</code>
|
|
<p>Single threaded version. Inlined.</p>
|
|
</li>
|
|
</ul>
|
|
|
|
<p>However, only <code>__exchange_and_add_dispatch</code>
|
|
and <code>__atomic_add_dispatch</code> should be used. These functions
|
|
can be used in a portable manner, regardless of the specific
|
|
environment. They are carefully designed to provide optimum efficiency
|
|
and speed, abstracting out atomic accesses when they are not required
|
|
(even on hosts that support compiler intrinsics for atomic
|
|
operations.)
|
|
</p>
|
|
|
|
<p>
|
|
In addition, there are two macros
|
|
</p>
|
|
|
|
<p>
|
|
<code>
|
|
_GLIBCXX_READ_MEM_BARRIER
|
|
</code>
|
|
</p>
|
|
<p>
|
|
<code>
|
|
_GLIBCXX_WRITE_MEM_BARRIER
|
|
</code>
|
|
</p>
|
|
|
|
<p>
|
|
Which expand to the appropriate write and read barrier required by the
|
|
host hardware and operating system.
|
|
</p>
|
|
|
|
<h3 class="left">
|
|
<a name="pthread_api">Pthread Interface</a>
|
|
</h3>
|
|
|
|
<p>A thin layer above IEEE 1003.1 (ie pthreads) is used to abstract
|
|
the thread interface for GCC. This layer is called "gthread," and is
|
|
comprised of one header file that wraps the host's default thread layer with
|
|
a POSIX-like interface.
|
|
</p>
|
|
|
|
<p> The file <gthr-default.h> points to the deduced wrapper for
|
|
the current host. In libstdc++ implementation files,
|
|
<bits/gthr.h> is used to select the proper gthreads file.
|
|
</p>
|
|
|
|
<p>Within libstdc++ sources, all calls to underlying thread functionality
|
|
use this layer. More detail as to the specific interface can be found in the source <a href="http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/gthr_8h-source.html">documentation</a>.
|
|
</p>
|
|
|
|
<p>By design, the gthread layer is interoperable with the types,
|
|
functions, and usage found in the usual <pthread.h> file,
|
|
including <code>pthread_t</code>, <code>pthread_once_t</code>, <code>pthread_create</code>,
|
|
etc.
|
|
</p>
|
|
|
|
<h3 class="left">
|
|
<a name="concur_api">Concurrence Interface</a>
|
|
</h3>
|
|
|
|
<p>The file <ext/concurrence.h> contains all the higher-level
|
|
constructs for playing with threads. In contrast to the atomics layer,
|
|
the concurrence layer consists largely of types. All types are defined within <code>namespace __gnu_cxx</code>.
|
|
</p>
|
|
|
|
<p>
|
|
These types can be used in a portable manner, regardless of the
|
|
specific environment. They are carefully designed to provide optimum
|
|
efficiency and speed, abstracting out underlying thread calls and
|
|
accesses when compiling for single-threaded situations (even on hosts
|
|
that support multiple threads.)
|
|
</p>
|
|
|
|
<p>The enumerated type <code>_Lock_policy</code> details the set of
|
|
available locking
|
|
policies: <code>_S_single</code>, <code>_S_mutex</code>,
|
|
and <code>_S_atomic</code>.
|
|
</p>
|
|
|
|
<ul>
|
|
<li><code>_S_single</code>
|
|
<p>Indicates single-threaded code that does not need locking.
|
|
</p>
|
|
|
|
</li>
|
|
<li><code>_S_mutex</code>
|
|
<p>Indicates multi-threaded code using thread-layer abstractions.
|
|
</p>
|
|
</li>
|
|
<li><code>_S_atomic</code>
|
|
<p>Indicates multi-threaded code using atomic operations.
|
|
</p>
|
|
</li>
|
|
</ul>
|
|
|
|
<p>The compile-time constant <code>__default_lock_policy</code> is set
|
|
to one of the three values above, depending on characteristics of the
|
|
host environment and the current compilation flags.
|
|
</p>
|
|
|
|
<p>Two more datatypes make up the rest of the
|
|
interface: <code>__mutex</code>, and <code>__scoped_lock</code>.
|
|
</p>
|
|
|
|
<p>
|
|
</p>
|
|
|
|
<p>The scoped lock idiom is well-discussed within the C++
|
|
community. This version takes a <code>__mutex</code> reference, and
|
|
locks it during construction of <code>__scoped_locke</code> and
|
|
unlocks it during destruction. This is an efficient way of locking
|
|
critical sections, while retaining exception-safety.
|
|
</p>
|
|
|
|
<p>Typical usage of the last two constructs is demonstrated as follows:
|
|
</p>
|
|
|
|
<pre>
|
|
#include <ext/concurrence.h>
|
|
|
|
namespace
|
|
{
|
|
__gnu_cxx::__mutex safe_base_mutex;
|
|
} // anonymous namespace
|
|
|
|
namespace other
|
|
{
|
|
void
|
|
foo()
|
|
{
|
|
__gnu_cxx::__scoped_lock sentry(safe_base_mutex);
|
|
for (int i = 0; i < max; ++i)
|
|
{
|
|
_Safe_iterator_base* __old = __iter;
|
|
__iter = __iter-<_M_next;
|
|
__old-<_M_detach_single();
|
|
}
|
|
}
|
|
</pre>
|
|
|
|
<p>In this sample code, an anonymous namespace is used to keep
|
|
the <code>__mutex</code> private to the compilation unit,
|
|
and <code>__scoped_lock</code> is used to guard access to the critical
|
|
section within the for loop, locking the mutex on creation and freeing
|
|
the mutex as control moves out of this block.
|
|
</p>
|
|
|
|
<p>Several exception classes are used to keep track of
|
|
concurrence-related errors. These classes
|
|
are: <code>__concurrence_lock_error</code>, <code>__concurrence_unlock_error</code>, <code>__concurrence_wait_error</code>,
|
|
and <code>__concurrence_broadcast_error</code>.
|
|
</p>
|
|
|
|
|
|
|
|
<h3 class="left">
|
|
<a name="atomic_impl">Details on builtin atomic support and library fallbacks</a>
|
|
</h3>
|
|
|
|
<p>The functions for atomic operations described above are either
|
|
implemented via compiler intrinsics (if the underlying host is
|
|
capable) or by library fallbacks.</p>
|
|
|
|
<p>Compiler intrinsics (builtins) are always preferred. However, as
|
|
the compiler builtins for atomics are not universally implemented,
|
|
using them directly is problematic, and can result in undefined
|
|
function calls. (An example of an undefined symbol from the use
|
|
of <code>__sync_fetch_and_add</code> on an unsupported host is a
|
|
missing reference to <code>__sync_fetch_and_add_4</code>.)
|
|
</p>
|
|
|
|
<p>In addition, on some hosts the compiler intrinsics are enabled
|
|
conditionally, via the <code>-march</code> command line flag. This makes
|
|
usage vary depending on the target hardware and the flags used during
|
|
compile.
|
|
</p>
|
|
|
|
<p> If builtins are possible, <code>_GLIBCXX_ATOMIC_BUILTINS</code>
|
|
will be defined.
|
|
</p>
|
|
|
|
|
|
<p>For the following hosts, intrinsics are enabled by default.
|
|
</p>
|
|
|
|
<ul>
|
|
<li>alpha</li>
|
|
<li>ia64</li>
|
|
<li>powerpc</li>
|
|
<li>s390</li>
|
|
</ul>
|
|
|
|
<p>For others, some form of <code>-march</code> may work. On
|
|
non-ancient x86 hardware, <code>-march=native</code> usually does the
|
|
trick.</p>
|
|
|
|
<p> For hosts without compiler intrinsics, but with capable
|
|
hardware, hand-crafted assembly is selected. This is the case for the following hosts:
|
|
</p>
|
|
|
|
<ul>
|
|
<li>cris</li>
|
|
<li>hppa</li>
|
|
<li>i386</li>
|
|
<li>i486</li>
|
|
<li>m48k</li>
|
|
<li>mips</li>
|
|
<li>sparc</li>
|
|
</ul>
|
|
|
|
<p>And for the rest, a simulated atomic lock via pthreads.
|
|
</p>
|
|
|
|
<p> Detailed information about compiler intrinsics for atomic operations can be found in the GCC <a href="http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html"> documentation</a>.
|
|
</p>
|
|
|
|
<p> More details on the library fallbacks from the porting <a href="http://gcc.gnu.org/onlinedocs/libstdc++/17_intro/porting.html#Thread%20safety">section</a>.
|
|
</p>
|
|
|
|
|
|
|
|
</body>
|
|
</html>
|
|
|