Home | History | Annotate | Line # | Download | only in manual
      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>
     21 contains all the higher-level
     22 constructs for playing with threads. In contrast to the atomics layer,
     23 the concurrence layer consists largely of types. All types are defined within <code>namespace __gnu_cxx</code>.
     24 </para>
     25 
     26 <para>
     27 These types can be used in a portable manner, regardless of the
     28 specific environment. They are carefully designed to provide optimum
     29 efficiency and speed, abstracting out underlying thread calls and
     30 accesses when compiling for single-threaded situations (even on hosts
     31 that support multiple threads.)
     32 </para>
     33 
     34 <para>The enumerated type <code>_Lock_policy</code> details the set of
     35 available locking
     36 policies: <code>_S_single</code>, <code>_S_mutex</code>,
     37 and <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
     57 to one of the three values above, depending on characteristics of the
     58 host environment and the current compilation flags.
     59 </para>
     60 
     61 <para>Two more datatypes make up the rest of the
     62 interface: <code>__mutex</code>, and <code>__scoped_lock</code>.
     63 </para>
     64 
     65 <para>The scoped lock idiom is well-discussed within the C++
     66 community. This version takes a <code>__mutex</code> reference, and
     67 locks it during construction of <code>__scoped_lock</code> and
     68 unlocks it during destruction. This is an efficient way of locking
     69 critical sections, while retaining exception-safety.
     70 These types have been superseded in the ISO C++ 2011 standard by the
     71 mutex 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>
     81 Two 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
     86 supporting atomic operations.
     87 </para>
     88 
     89 <para>
     90 The two functions functions are:
     91 </para>
     92 
     93 <programlisting>
     94 _Atomic_word
     95 __exchange_and_add_dispatch(volatile _Atomic_word*, int);
     96 
     97 void
     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>
    125 These functions forward to one of several specialized helper
    126 functions, 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>
    136 Calls 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
    143 can be used, otherwise resolved at link time to a non-builtin code
    144 sequence.
    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>
    155 and <code>__atomic_add_dispatch</code> should be used. These functions
    156 can be used in a portable manner, regardless of the specific
    157 environment. They are carefully designed to provide optimum efficiency
    158 and speed, abstracting out atomic accesses when they are not required
    159 (even on hosts that support compiler intrinsics for atomic
    160 operations.)
    161 </para>
    162 
    163 <para>
    164 In 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>
    179 Which expand to the appropriate write and read barrier required by the
    180 host 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 Built-in Atomic Functions</title></info>
    191 
    192 
    193 <para>The functions for atomic operations described above are either
    194 implemented via compiler intrinsics (if the underlying host is
    195 capable) or by library fallbacks.</para>
    196 
    197 <para>Compiler intrinsics (builtins) are always preferred.  However, as
    198 the compiler builtins for atomics are not universally implemented,
    199 using them directly is problematic, and can result in undefined
    200 function calls.
    201 </para>
    202 
    203 <para>Prior to GCC 4.7 the older <code>__sync</code> intrinsics were used.
    204 An example of an undefined symbol from the use
    205 of <code>__sync_fetch_and_add</code> on an unsupported host is a
    206 missing reference to <code>__sync_fetch_and_add_4</code>.
    207 </para>
    208 
    209 <para>Current releases use the newer <code>__atomic</code> intrinsics,
    210 which are implemented by library calls if the hardware doesn't support them.
    211 Undefined references to functions like
    212 <code>__atomic_is_lock_free</code> should be resolved by linking to
    213 <filename class="libraryfile">libatomic</filename>, which is usually
    214 installed alongside libstdc++.
    215 </para>
    216 
    217 <para>In addition, on some hosts the compiler intrinsics are enabled
    218 conditionally, via the <code>-march</code> command line flag. This makes
    219 usage vary depending on the target hardware and the flags used during
    220 compile.
    221 </para>
    222 
    223 
    224 
    225 <para>
    226 <remark>
    227 Incomplete/inconsistent. This is only C++11.
    228 </remark>
    229 </para>
    230 
    231 <para>
    232 If builtins are possible for bool-sized integral types,
    233 <code>ATOMIC_BOOL_LOCK_FREE</code> will be defined.
    234 If builtins are possible for int-sized integral types,
    235 <code>ATOMIC_INT_LOCK_FREE</code> will be defined.
    236 </para>
    237 
    238 
    239 <para>For the following hosts, intrinsics are enabled by default.
    240 </para>
    241 
    242 <itemizedlist>
    243   <listitem><para>alpha</para></listitem>
    244   <listitem><para>ia64</para></listitem>
    245   <listitem><para>powerpc</para></listitem>
    246   <listitem><para>s390</para></listitem>
    247 </itemizedlist>
    248 
    249 <para>For others, some form of <code>-march</code> may work. On
    250 non-ancient x86 hardware, <code>-march=native</code> usually does the
    251 trick.</para>
    252 
    253 <para> For hosts without compiler intrinsics, but with capable
    254 hardware, hand-crafted assembly is selected. This is the case for the following hosts:
    255 </para>
    256 
    257 <itemizedlist>
    258   <listitem><para>cris</para></listitem>
    259   <listitem><para>hppa</para></listitem>
    260   <listitem><para>i386</para></listitem>
    261   <listitem><para>i486</para></listitem>
    262   <listitem><para>m48k</para></listitem>
    263   <listitem><para>mips</para></listitem>
    264   <listitem><para>sparc</para></listitem>
    265 </itemizedlist>
    266 
    267 <para>And for the rest, a simulated atomic lock via pthreads.
    268 </para>
    269 
    270 <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/_005f_005fatomic-Builtins.html"> documentation</link>.
    271 </para>
    272 
    273 <para> More details on the library fallbacks from the porting <link linkend="internals.thread_safety">section</link>.
    274 </para>
    275 
    276 
    277   </section>
    278   <section xml:id="manual.ext.concurrency.impl.thread" xreflabel="Pthread"><info><title>Thread Abstraction</title></info>
    279 
    280 
    281 <para>A thin layer above IEEE 1003.1 (i.e. pthreads) is used to abstract
    282 the thread interface for GCC. This layer is called "gthread," and is
    283 comprised of one header file that wraps the host's default thread layer with
    284 a POSIX-like interface.
    285 </para>
    286 
    287 <para> The file &lt;gthr-default.h&gt; points to the deduced wrapper for
    288 the current host. In libstdc++ implementation files,
    289 &lt;bits/gthr.h&gt; is used to select the proper gthreads file.
    290 </para>
    291 
    292 <para>Within libstdc++ sources, all calls to underlying thread functionality
    293 use 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/index.html">documentation</link>.
    294 </para>
    295 
    296 <para>By design, the gthread layer is interoperable with the types,
    297 functions, and usage found in the usual &lt;pthread.h&gt; file,
    298 including <code>pthread_t</code>, <code>pthread_once_t</code>, <code>pthread_create</code>,
    299 etc.
    300 </para>
    301 
    302   </section>
    303 </section>
    304 
    305 <section xml:id="manual.ext.concurrency.use" xreflabel="Use"><info><title>Use</title></info>
    306 <?dbhtml filename="ext_concurrency_use.html"?>
    307 
    308 
    309 <para>Typical usage of the last two constructs is demonstrated as follows:
    310 </para>
    311 
    312 <programlisting>
    313 #include &lt;ext/concurrence.h&gt;
    314 
    315 namespace
    316 {
    317   __gnu_cxx::__mutex safe_base_mutex;
    318 } // anonymous namespace
    319 
    320 namespace other
    321 {
    322   void
    323   foo()
    324   {
    325     __gnu_cxx::__scoped_lock sentry(safe_base_mutex);
    326     for (int i = 0; i &lt; max;  ++i)
    327       {
    328 	_Safe_iterator_base* __old = __iter;
    329 	__iter = __iter-&lt;_M_next;
    330 	__old-&lt;_M_detach_single();
    331       }
    332 }
    333 </programlisting>
    334 
    335 <para>In this sample code, an anonymous namespace is used to keep
    336 the <code>__mutex</code> private to the compilation unit,
    337 and <code>__scoped_lock</code> is used to guard access to the critical
    338 section within the for loop, locking the mutex on creation and freeing
    339 the mutex as control moves out of this block.
    340 </para>
    341 
    342 <para>Several exception classes are used to keep track of
    343 concurrence-related errors. These classes
    344 are: <code>__concurrence_lock_error</code>, <code>__concurrence_unlock_error</code>, <code>__concurrence_wait_error</code>,
    345 and <code>__concurrence_broadcast_error</code>.
    346 </para>
    347 
    348 
    349 </section>
    350 
    351 </chapter>
    352