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"><ext/concurrence.h></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"><mutex></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<ext/atomicity.h>, 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 <gthr-default.h> points to the deduced wrapper for 276the current host. In libstdc++ implementation files, 277<bits/gthr.h> 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 <pthread.h> 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 <ext/concurrence.h> 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 < max; ++i) 315 { 316 _Safe_iterator_base* __old = __iter; 317 __iter = __iter-<_M_next; 318 __old-<_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