OSDN Git Service

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