OSDN Git Service

2009-04-15 Benjamin Kosnik <bkoz@redhat.com>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / doc / xml / manual / concurrency.xml
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 &lt;ext/concurrence.h&gt; contains all the higher-level
29 constructs for playing with threads. In contrast to the atomics layer,
30 the concurrence layer consists largely of types. All types are defined within <code>namespace __gnu_cxx</code>.
31 </para>
32
33 <para>
34 These types can be used in a portable manner, regardless of the
35 specific environment. They are carefully designed to provide optimum
36 efficiency and speed, abstracting out underlying thread calls and
37 accesses when compiling for single-threaded situations (even on hosts
38 that support multiple threads.)
39 </para>
40
41 <para>The enumerated type <code>_Lock_policy</code> details the set of
42 available locking
43 policies: <code>_S_single</code>, <code>_S_mutex</code>,
44 and <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
64 to one of the three values above, depending on characteristics of the
65 host environment and the current compilation flags.
66 </para>
67
68 <para>Two more datatypes make up the rest of the
69 interface: <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++
76 community. This version takes a <code>__mutex</code> reference, and
77 locks it during construction of <code>__scoped_locke</code> and
78 unlocks it during destruction. This is an efficient way of locking
79 critical 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>
88 Two 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
93 supporting atomic operations.
94 </para>
95
96 <para>
97 The two functions functions are:
98 </para>
99
100 <programlisting>
101 _Atomic_word
102 __exchange_and_add_dispatch(volatile _Atomic_word*, int);
103
104 void
105 __atomic_add_dispatch(volatile _Atomic_word*, int);
106 </programlisting>
107
108 <para>Both of these functions are declared in the header file
109 &lt;ext/atomicity.h&gt;, 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>
132 These functions forward to one of several specialized helper
133 functions, 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>
143 Calls 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
150 can be used, otherwise resolved at link time to a non-builtin code
151 sequence.
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>
162 and <code>__atomic_add_dispatch</code> should be used. These functions
163 can be used in a portable manner, regardless of the specific
164 environment. They are carefully designed to provide optimum efficiency
165 and speed, abstracting out atomic accesses when they are not required
166 (even on hosts that support compiler intrinsics for atomic
167 operations.)
168 </para>
169
170 <para>
171 In 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>
186 Which expand to the appropriate write and read barrier required by the
187 host 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
200 implemented via compiler intrinsics (if the underlying host is
201 capable) or by library fallbacks.</para>
202
203 <para>Compiler intrinsics (builtins) are always preferred.  However, as
204 the compiler builtins for atomics are not universally implemented,
205 using them directly is problematic, and can result in undefined
206 function calls. (An example of an undefined symbol from the use
207 of <code>__sync_fetch_and_add</code> on an unsupported host is a
208 missing reference to <code>__sync_fetch_and_add_4</code>.)
209 </para>
210
211 <para>In addition, on some hosts the compiler intrinsics are enabled
212 conditionally, via the <code>-march</code> command line flag. This makes
213 usage vary depending on the target hardware and the flags used during
214 compile.
215 </para>
216
217 <para> 
218 If builtins are possible for bool-sized integral types,
219 <code>_GLIBCXX_ATOMIC_BUILTINS_1</code> will be defined.
220 If 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
236 non-ancient x86 hardware, <code>-march=native</code> usually does the
237 trick.</para>
238
239 <para> For hosts without compiler intrinsics, but with capable
240 hardware, 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 <ulink url="http://gcc.gnu.org/onlinedocs/libstdc++/17_intro/porting.html#Thread%20safety">section</ulink>.
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
268 the thread interface for GCC. This layer is called "gthread," and is
269 comprised of one header file that wraps the host's default thread layer with
270 a POSIX-like interface.
271 </para>
272
273 <para> The file &lt;gthr-default.h&gt; points to the deduced wrapper for
274 the current host. In libstdc++ implementation files,
275 &lt;bits/gthr.h&gt; is used to select the proper gthreads file.
276 </para>
277
278 <para>Within libstdc++ sources, all calls to underlying thread functionality
279 use 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/gthr_8h-source.html">documentation</ulink>.
280 </para>
281
282 <para>By design, the gthread layer is interoperable with the types,
283 functions, and usage found in the usual &lt;pthread.h&gt; file,
284 including <code>pthread_t</code>, <code>pthread_once_t</code>, <code>pthread_create</code>,
285 etc.
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 &lt;ext/concurrence.h&gt;
300
301 namespace
302 {
303   __gnu_cxx::__mutex safe_base_mutex;
304 } // anonymous namespace
305
306 namespace other
307 {
308   void
309   foo()
310   {
311     __gnu_cxx::__scoped_lock sentry(safe_base_mutex);
312     for (int i = 0; i &lt; max;  ++i)
313       {
314         _Safe_iterator_base* __old = __iter;
315         __iter = __iter-&lt;_M_next;
316         __old-&lt;_M_detach_single();
317       }
318 }
319 </programlisting>
320
321 <para>In this sample code, an anonymous namespace is used to keep
322 the <code>__mutex</code> private to the compilation unit,
323 and <code>__scoped_lock</code> is used to guard access to the critical
324 section within the for loop, locking the mutex on creation and freeing
325 the mutex as control moves out of this block.
326 </para>
327
328 <para>Several exception classes are used to keep track of
329 concurrence-related errors. These classes
330 are: <code>__concurrence_lock_error</code>, <code>__concurrence_unlock_error</code>, <code>__concurrence_wait_error</code>,
331 and <code>__concurrence_broadcast_error</code>.
332 </para>
333
334
335 </sect1>
336
337 </chapter>