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