xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/doc/xml/manual/concurrency_extensions.xml (revision 946379e7b37692fc43f68eb0d1c10daa0a7f3b6c)
1<chapter xmlns="http://docbook.org/ns/docbook" version="5.0"
2	 xml:id="manual.ext.concurrency" xreflabel="Concurrency Extensions">
3<?dbhtml filename="ext_concurrency.html"?>
4
5<info><title>Concurrency</title>
6  <keywordset>
7    <keyword>ISO C++</keyword>
8    <keyword>library</keyword>
9  </keywordset>
10</info>
11
12
13
14<section xml:id="manual.ext.concurrency.design" xreflabel="Design"><info><title>Design</title></info>
15
16
17  <section xml:id="manual.ext.concurrency.design.threads" xreflabel="Threads API"><info><title>Interface to Locks and Mutexes</title></info>
18
19
20<para>The file <filename class="headerfile">&lt;ext/concurrence.h&gt;</filename>
21contains all the higher-level
22constructs for playing with threads. In contrast to the atomics layer,
23the concurrence layer consists largely of types. All types are defined within <code>namespace __gnu_cxx</code>.
24</para>
25
26<para>
27These types can be used in a portable manner, regardless of the
28specific environment. They are carefully designed to provide optimum
29efficiency and speed, abstracting out underlying thread calls and
30accesses when compiling for single-threaded situations (even on hosts
31that support multiple threads.)
32</para>
33
34<para>The enumerated type <code>_Lock_policy</code> details the set of
35available locking
36policies: <code>_S_single</code>, <code>_S_mutex</code>,
37and <code>_S_atomic</code>.
38</para>
39
40<itemizedlist>
41<listitem><para><code>_S_single</code></para>
42<para>Indicates single-threaded code that does not need locking.
43</para>
44
45</listitem>
46<listitem><para><code>_S_mutex</code></para>
47<para>Indicates multi-threaded code using thread-layer abstractions.
48</para>
49</listitem>
50<listitem><para><code>_S_atomic</code></para>
51<para>Indicates multi-threaded code using atomic operations.
52</para>
53</listitem>
54</itemizedlist>
55
56<para>The compile-time constant <code>__default_lock_policy</code> is set
57to one of the three values above, depending on characteristics of the
58host environment and the current compilation flags.
59</para>
60
61<para>Two more datatypes make up the rest of the
62interface: <code>__mutex</code>, and <code>__scoped_lock</code>.
63</para>
64
65<para>The scoped lock idiom is well-discussed within the C++
66community. This version takes a <code>__mutex</code> reference, and
67locks it during construction of <code>__scoped_lock</code> and
68unlocks it during destruction. This is an efficient way of locking
69critical sections, while retaining exception-safety.
70These types have been superseded in the ISO C++ 2011 standard by the
71mutex and lock types defined in the header
72<filename class="headerfile">&lt;mutex&gt;</filename>.
73</para>
74  </section>
75
76  <section xml:id="manual.ext.concurrency.design.atomics" xreflabel="Atomic API"><info><title>Interface to Atomic Functions</title></info>
77
78
79
80<para>
81Two functions and one type form the base of atomic support.
82</para>
83
84
85<para>The type <code>_Atomic_word</code> is a signed integral type
86supporting atomic operations.
87</para>
88
89<para>
90The two functions functions are:
91</para>
92
93<programlisting>
94_Atomic_word
95__exchange_and_add_dispatch(volatile _Atomic_word*, int);
96
97void
98__atomic_add_dispatch(volatile _Atomic_word*, int);
99</programlisting>
100
101<para>Both of these functions are declared in the header file
102&lt;ext/atomicity.h&gt;, and are in <code>namespace __gnu_cxx</code>.
103</para>
104
105<itemizedlist>
106<listitem><para>
107<code>
108__exchange_and_add_dispatch
109</code>
110</para>
111<para>Adds the second argument's value to the first argument. Returns the old value.
112</para>
113</listitem>
114<listitem><para>
115<code>
116__atomic_add_dispatch
117</code>
118</para>
119<para>Adds the second argument's value to the first argument. Has no return value.
120</para>
121</listitem>
122</itemizedlist>
123
124<para>
125These functions forward to one of several specialized helper
126functions, depending on the circumstances. For instance,
127</para>
128
129<para>
130<code>
131__exchange_and_add_dispatch
132</code>
133</para>
134
135<para>
136Calls through to either of:
137</para>
138
139<itemizedlist>
140<listitem><para><code>__exchange_and_add</code>
141</para>
142<para>Multi-thread version. Inlined if compiler-generated builtin atomics
143can be used, otherwise resolved at link time to a non-builtin code
144sequence.
145</para>
146</listitem>
147
148<listitem><para><code>__exchange_and_add_single</code>
149</para>
150<para>Single threaded version. Inlined.</para>
151</listitem>
152</itemizedlist>
153
154<para>However, only <code>__exchange_and_add_dispatch</code>
155and <code>__atomic_add_dispatch</code> should be used. These functions
156can be used in a portable manner, regardless of the specific
157environment. They are carefully designed to provide optimum efficiency
158and speed, abstracting out atomic accesses when they are not required
159(even on hosts that support compiler intrinsics for atomic
160operations.)
161</para>
162
163<para>
164In addition, there are two macros
165</para>
166
167<para>
168<code>
169_GLIBCXX_READ_MEM_BARRIER
170</code>
171</para>
172<para>
173<code>
174_GLIBCXX_WRITE_MEM_BARRIER
175</code>
176</para>
177
178<para>
179Which expand to the appropriate write and read barrier required by the
180host hardware and operating system.
181</para>
182  </section>
183
184</section>
185
186
187<section xml:id="manual.ext.concurrency.impl" xreflabel="Implementation"><info><title>Implementation</title></info>
188  <?dbhtml filename="ext_concurrency_impl.html"?>
189
190  <section xml:id="manual.ext.concurrency.impl.atomic_fallbacks" xreflabel="Atomic F"><info><title>Using Builtin Atomic Functions</title></info>
191
192
193<para>The functions for atomic operations described above are either
194implemented via compiler intrinsics (if the underlying host is
195capable) or by library fallbacks.</para>
196
197<para>Compiler intrinsics (builtins) are always preferred.  However, as
198the compiler builtins for atomics are not universally implemented,
199using them directly is problematic, and can result in undefined
200function calls. (An example of an undefined symbol from the use
201of <code>__sync_fetch_and_add</code> on an unsupported host is a
202missing reference to <code>__sync_fetch_and_add_4</code>.)
203</para>
204
205<para>In addition, on some hosts the compiler intrinsics are enabled
206conditionally, via the <code>-march</code> command line flag. This makes
207usage vary depending on the target hardware and the flags used during
208compile.
209</para>
210
211
212
213<para>
214<remark>
215Incomplete/inconsistent. This is only C++11.
216</remark>
217</para>
218
219<para>
220If builtins are possible for bool-sized integral types,
221<code>ATOMIC_BOOL_LOCK_FREE</code> will be defined.
222If builtins are possible for int-sized integral types,
223<code>ATOMIC_INT_LOCK_FREE</code> will be defined.
224</para>
225
226
227<para>For the following hosts, intrinsics are enabled by default.
228</para>
229
230<itemizedlist>
231  <listitem><para>alpha</para></listitem>
232  <listitem><para>ia64</para></listitem>
233  <listitem><para>powerpc</para></listitem>
234  <listitem><para>s390</para></listitem>
235</itemizedlist>
236
237<para>For others, some form of <code>-march</code> may work. On
238non-ancient x86 hardware, <code>-march=native</code> usually does the
239trick.</para>
240
241<para> For hosts without compiler intrinsics, but with capable
242hardware, hand-crafted assembly is selected. This is the case for the following hosts:
243</para>
244
245<itemizedlist>
246  <listitem><para>cris</para></listitem>
247  <listitem><para>hppa</para></listitem>
248  <listitem><para>i386</para></listitem>
249  <listitem><para>i486</para></listitem>
250  <listitem><para>m48k</para></listitem>
251  <listitem><para>mips</para></listitem>
252  <listitem><para>sparc</para></listitem>
253</itemizedlist>
254
255<para>And for the rest, a simulated atomic lock via pthreads.
256</para>
257
258<para> Detailed information about compiler intrinsics for atomic operations can be found in the GCC <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html"> documentation</link>.
259</para>
260
261<para> More details on the library fallbacks from the porting <link linkend="internals.thread_safety">section</link>.
262</para>
263
264
265  </section>
266  <section xml:id="manual.ext.concurrency.impl.thread" xreflabel="Pthread"><info><title>Thread Abstraction</title></info>
267
268
269<para>A thin layer above IEEE 1003.1 (i.e. pthreads) is used to abstract
270the thread interface for GCC. This layer is called "gthread," and is
271comprised of one header file that wraps the host's default thread layer with
272a POSIX-like interface.
273</para>
274
275<para> The file &lt;gthr-default.h&gt; points to the deduced wrapper for
276the current host. In libstdc++ implementation files,
277&lt;bits/gthr.h&gt; is used to select the proper gthreads file.
278</para>
279
280<para>Within libstdc++ sources, all calls to underlying thread functionality
281use this layer. More detail as to the specific interface can be found in the source <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a00883_source.html">documentation</link>.
282</para>
283
284<para>By design, the gthread layer is interoperable with the types,
285functions, and usage found in the usual &lt;pthread.h&gt; file,
286including <code>pthread_t</code>, <code>pthread_once_t</code>, <code>pthread_create</code>,
287etc.
288</para>
289
290  </section>
291</section>
292
293<section xml:id="manual.ext.concurrency.use" xreflabel="Use"><info><title>Use</title></info>
294<?dbhtml filename="ext_concurrency_use.html"?>
295
296
297<para>Typical usage of the last two constructs is demonstrated as follows:
298</para>
299
300<programlisting>
301#include &lt;ext/concurrence.h&gt;
302
303namespace
304{
305  __gnu_cxx::__mutex safe_base_mutex;
306} // anonymous namespace
307
308namespace other
309{
310  void
311  foo()
312  {
313    __gnu_cxx::__scoped_lock sentry(safe_base_mutex);
314    for (int i = 0; i &lt; max;  ++i)
315      {
316	_Safe_iterator_base* __old = __iter;
317	__iter = __iter-&lt;_M_next;
318	__old-&lt;_M_detach_single();
319      }
320}
321</programlisting>
322
323<para>In this sample code, an anonymous namespace is used to keep
324the <code>__mutex</code> private to the compilation unit,
325and <code>__scoped_lock</code> is used to guard access to the critical
326section within the for loop, locking the mutex on creation and freeing
327the mutex as control moves out of this block.
328</para>
329
330<para>Several exception classes are used to keep track of
331concurrence-related errors. These classes
332are: <code>__concurrence_lock_error</code>, <code>__concurrence_unlock_error</code>, <code>__concurrence_wait_error</code>,
333and <code>__concurrence_broadcast_error</code>.
334</para>
335
336
337</section>
338
339</chapter>
340