Chris@102
|
1 /*
|
Chris@102
|
2 * Distributed under the Boost Software License, Version 1.0.
|
Chris@102
|
3 * (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@102
|
4 * http://www.boost.org/LICENSE_1_0.txt)
|
Chris@102
|
5 *
|
Chris@102
|
6 * Copyright (c) 2009 Helge Bahmann
|
Chris@102
|
7 * Copyright (c) 2013 Tim Blechmann
|
Chris@102
|
8 * Copyright (c) 2014 Andrey Semashev
|
Chris@102
|
9 */
|
Chris@102
|
10 /*!
|
Chris@102
|
11 * \file atomic/detail/ops_gcc_alpha.hpp
|
Chris@102
|
12 *
|
Chris@102
|
13 * This header contains implementation of the \c operations template.
|
Chris@102
|
14 */
|
Chris@102
|
15
|
Chris@102
|
16 #ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_ALPHA_HPP_INCLUDED_
|
Chris@102
|
17 #define BOOST_ATOMIC_DETAIL_OPS_GCC_ALPHA_HPP_INCLUDED_
|
Chris@102
|
18
|
Chris@102
|
19 #include <boost/memory_order.hpp>
|
Chris@102
|
20 #include <boost/atomic/detail/config.hpp>
|
Chris@102
|
21 #include <boost/atomic/detail/storage_type.hpp>
|
Chris@102
|
22 #include <boost/atomic/detail/operations_fwd.hpp>
|
Chris@102
|
23 #include <boost/atomic/capabilities.hpp>
|
Chris@102
|
24
|
Chris@102
|
25 #ifdef BOOST_HAS_PRAGMA_ONCE
|
Chris@102
|
26 #pragma once
|
Chris@102
|
27 #endif
|
Chris@102
|
28
|
Chris@102
|
29 namespace boost {
|
Chris@102
|
30 namespace atomics {
|
Chris@102
|
31 namespace detail {
|
Chris@102
|
32
|
Chris@102
|
33 /*
|
Chris@102
|
34 Refer to http://h71000.www7.hp.com/doc/82final/5601/5601pro_004.html
|
Chris@102
|
35 (HP OpenVMS systems documentation) and the Alpha Architecture Reference Manual.
|
Chris@102
|
36 */
|
Chris@102
|
37
|
Chris@102
|
38 /*
|
Chris@102
|
39 NB: The most natural thing would be to write the increment/decrement
|
Chris@102
|
40 operators along the following lines:
|
Chris@102
|
41
|
Chris@102
|
42 __asm__ __volatile__
|
Chris@102
|
43 (
|
Chris@102
|
44 "1: ldl_l %0,%1 \n"
|
Chris@102
|
45 "addl %0,1,%0 \n"
|
Chris@102
|
46 "stl_c %0,%1 \n"
|
Chris@102
|
47 "beq %0,1b\n"
|
Chris@102
|
48 : "=&b" (tmp)
|
Chris@102
|
49 : "m" (value)
|
Chris@102
|
50 : "cc"
|
Chris@102
|
51 );
|
Chris@102
|
52
|
Chris@102
|
53 However according to the comments on the HP website and matching
|
Chris@102
|
54 comments in the Linux kernel sources this defies branch prediction,
|
Chris@102
|
55 as the cpu assumes that backward branches are always taken; so
|
Chris@102
|
56 instead copy the trick from the Linux kernel, introduce a forward
|
Chris@102
|
57 branch and back again.
|
Chris@102
|
58
|
Chris@102
|
59 I have, however, had a hard time measuring the difference between
|
Chris@102
|
60 the two versions in microbenchmarks -- I am leaving it in nevertheless
|
Chris@102
|
61 as it apparently does not hurt either.
|
Chris@102
|
62 */
|
Chris@102
|
63
|
Chris@102
|
64 struct gcc_alpha_operations_base
|
Chris@102
|
65 {
|
Chris@102
|
66 static BOOST_FORCEINLINE void fence_before(memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
67 {
|
Chris@102
|
68 if ((order & memory_order_release) != 0)
|
Chris@102
|
69 __asm__ __volatile__ ("mb" ::: "memory");
|
Chris@102
|
70 }
|
Chris@102
|
71
|
Chris@102
|
72 static BOOST_FORCEINLINE void fence_after(memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
73 {
|
Chris@102
|
74 if ((order & (memory_order_consume | memory_order_acquire)) != 0)
|
Chris@102
|
75 __asm__ __volatile__ ("mb" ::: "memory");
|
Chris@102
|
76 }
|
Chris@102
|
77
|
Chris@102
|
78 static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
79 {
|
Chris@102
|
80 if (order == memory_order_seq_cst)
|
Chris@102
|
81 __asm__ __volatile__ ("mb" ::: "memory");
|
Chris@102
|
82 }
|
Chris@102
|
83 };
|
Chris@102
|
84
|
Chris@102
|
85
|
Chris@102
|
86 template< bool Signed >
|
Chris@102
|
87 struct operations< 4u, Signed > :
|
Chris@102
|
88 public gcc_alpha_operations_base
|
Chris@102
|
89 {
|
Chris@102
|
90 typedef typename make_storage_type< 4u, Signed >::type storage_type;
|
Chris@102
|
91
|
Chris@102
|
92 static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
93 {
|
Chris@102
|
94 fence_before(order);
|
Chris@102
|
95 storage = v;
|
Chris@102
|
96 fence_after_store(order);
|
Chris@102
|
97 }
|
Chris@102
|
98
|
Chris@102
|
99 static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
100 {
|
Chris@102
|
101 storage_type v = storage;
|
Chris@102
|
102 fence_after(order);
|
Chris@102
|
103 return v;
|
Chris@102
|
104 }
|
Chris@102
|
105
|
Chris@102
|
106 static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
107 {
|
Chris@102
|
108 storage_type original, tmp;
|
Chris@102
|
109 fence_before(order);
|
Chris@102
|
110 __asm__ __volatile__
|
Chris@102
|
111 (
|
Chris@102
|
112 "1:\n"
|
Chris@102
|
113 "mov %3, %1\n"
|
Chris@102
|
114 "ldl_l %0, %2\n"
|
Chris@102
|
115 "stl_c %1, %2\n"
|
Chris@102
|
116 "beq %1, 2f\n"
|
Chris@102
|
117
|
Chris@102
|
118 ".subsection 2\n"
|
Chris@102
|
119 "2: br 1b\n"
|
Chris@102
|
120 ".previous\n"
|
Chris@102
|
121
|
Chris@102
|
122 : "=&r" (original), // %0
|
Chris@102
|
123 "=&r" (tmp) // %1
|
Chris@102
|
124 : "m" (storage), // %2
|
Chris@102
|
125 "r" (v) // %3
|
Chris@102
|
126 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
|
Chris@102
|
127 );
|
Chris@102
|
128 fence_after(order);
|
Chris@102
|
129 return original;
|
Chris@102
|
130 }
|
Chris@102
|
131
|
Chris@102
|
132 static BOOST_FORCEINLINE bool compare_exchange_weak(
|
Chris@102
|
133 storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
|
Chris@102
|
134 {
|
Chris@102
|
135 fence_before(success_order);
|
Chris@102
|
136 int success;
|
Chris@102
|
137 storage_type current;
|
Chris@102
|
138 __asm__ __volatile__
|
Chris@102
|
139 (
|
Chris@102
|
140 "1:\n"
|
Chris@102
|
141 "ldl_l %2, %4\n" // current = *(&storage)
|
Chris@102
|
142 "cmpeq %2, %0, %3\n" // success = current == expected
|
Chris@102
|
143 "mov %2, %0\n" // expected = current
|
Chris@102
|
144 "beq %3, 2f\n" // if (success == 0) goto end
|
Chris@102
|
145 "stl_c %1, %4\n" // storage = desired; desired = store succeeded
|
Chris@102
|
146 "mov %1, %3\n" // success = desired
|
Chris@102
|
147 "2:\n"
|
Chris@102
|
148 : "+&r" (expected), // %0
|
Chris@102
|
149 "+&r" (desired), // %1
|
Chris@102
|
150 "=&r" (current), // %2
|
Chris@102
|
151 "=&r" (success) // %3
|
Chris@102
|
152 : "m" (storage) // %4
|
Chris@102
|
153 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
|
Chris@102
|
154 );
|
Chris@102
|
155 if (success)
|
Chris@102
|
156 fence_after(success_order);
|
Chris@102
|
157 else
|
Chris@102
|
158 fence_after(failure_order);
|
Chris@102
|
159 return !!success;
|
Chris@102
|
160 }
|
Chris@102
|
161
|
Chris@102
|
162 static BOOST_FORCEINLINE bool compare_exchange_strong(
|
Chris@102
|
163 storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
|
Chris@102
|
164 {
|
Chris@102
|
165 int success;
|
Chris@102
|
166 storage_type current, tmp;
|
Chris@102
|
167 fence_before(success_order);
|
Chris@102
|
168 __asm__ __volatile__
|
Chris@102
|
169 (
|
Chris@102
|
170 "1:\n"
|
Chris@102
|
171 "mov %5, %1\n" // tmp = desired
|
Chris@102
|
172 "ldl_l %2, %4\n" // current = *(&storage)
|
Chris@102
|
173 "cmpeq %2, %0, %3\n" // success = current == expected
|
Chris@102
|
174 "mov %2, %0\n" // expected = current
|
Chris@102
|
175 "beq %3, 2f\n" // if (success == 0) goto end
|
Chris@102
|
176 "stl_c %1, %4\n" // storage = tmp; tmp = store succeeded
|
Chris@102
|
177 "beq %1, 3f\n" // if (tmp == 0) goto retry
|
Chris@102
|
178 "mov %1, %3\n" // success = tmp
|
Chris@102
|
179 "2:\n"
|
Chris@102
|
180
|
Chris@102
|
181 ".subsection 2\n"
|
Chris@102
|
182 "3: br 1b\n"
|
Chris@102
|
183 ".previous\n"
|
Chris@102
|
184
|
Chris@102
|
185 : "+&r" (expected), // %0
|
Chris@102
|
186 "=&r" (tmp), // %1
|
Chris@102
|
187 "=&r" (current), // %2
|
Chris@102
|
188 "=&r" (success) // %3
|
Chris@102
|
189 : "m" (storage), // %4
|
Chris@102
|
190 "r" (desired) // %5
|
Chris@102
|
191 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
|
Chris@102
|
192 );
|
Chris@102
|
193 if (success)
|
Chris@102
|
194 fence_after(success_order);
|
Chris@102
|
195 else
|
Chris@102
|
196 fence_after(failure_order);
|
Chris@102
|
197 return !!success;
|
Chris@102
|
198 }
|
Chris@102
|
199
|
Chris@102
|
200 static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
201 {
|
Chris@102
|
202 storage_type original, modified;
|
Chris@102
|
203 fence_before(order);
|
Chris@102
|
204 __asm__ __volatile__
|
Chris@102
|
205 (
|
Chris@102
|
206 "1:\n"
|
Chris@102
|
207 "ldl_l %0, %2\n"
|
Chris@102
|
208 "addl %0, %3, %1\n"
|
Chris@102
|
209 "stl_c %1, %2\n"
|
Chris@102
|
210 "beq %1, 2f\n"
|
Chris@102
|
211
|
Chris@102
|
212 ".subsection 2\n"
|
Chris@102
|
213 "2: br 1b\n"
|
Chris@102
|
214 ".previous\n"
|
Chris@102
|
215
|
Chris@102
|
216 : "=&r" (original), // %0
|
Chris@102
|
217 "=&r" (modified) // %1
|
Chris@102
|
218 : "m" (storage), // %2
|
Chris@102
|
219 "r" (v) // %3
|
Chris@102
|
220 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
|
Chris@102
|
221 );
|
Chris@102
|
222 fence_after(order);
|
Chris@102
|
223 return original;
|
Chris@102
|
224 }
|
Chris@102
|
225
|
Chris@102
|
226 static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
227 {
|
Chris@102
|
228 storage_type original, modified;
|
Chris@102
|
229 fence_before(order);
|
Chris@102
|
230 __asm__ __volatile__
|
Chris@102
|
231 (
|
Chris@102
|
232 "1:\n"
|
Chris@102
|
233 "ldl_l %0, %2\n"
|
Chris@102
|
234 "subl %0, %3, %1\n"
|
Chris@102
|
235 "stl_c %1, %2\n"
|
Chris@102
|
236 "beq %1, 2f\n"
|
Chris@102
|
237
|
Chris@102
|
238 ".subsection 2\n"
|
Chris@102
|
239 "2: br 1b\n"
|
Chris@102
|
240 ".previous\n"
|
Chris@102
|
241
|
Chris@102
|
242 : "=&r" (original), // %0
|
Chris@102
|
243 "=&r" (modified) // %1
|
Chris@102
|
244 : "m" (storage), // %2
|
Chris@102
|
245 "r" (v) // %3
|
Chris@102
|
246 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
|
Chris@102
|
247 );
|
Chris@102
|
248 fence_after(order);
|
Chris@102
|
249 return original;
|
Chris@102
|
250 }
|
Chris@102
|
251
|
Chris@102
|
252 static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
253 {
|
Chris@102
|
254 storage_type original, modified;
|
Chris@102
|
255 fence_before(order);
|
Chris@102
|
256 __asm__ __volatile__
|
Chris@102
|
257 (
|
Chris@102
|
258 "1:\n"
|
Chris@102
|
259 "ldl_l %0, %2\n"
|
Chris@102
|
260 "and %0, %3, %1\n"
|
Chris@102
|
261 "stl_c %1, %2\n"
|
Chris@102
|
262 "beq %1, 2f\n"
|
Chris@102
|
263
|
Chris@102
|
264 ".subsection 2\n"
|
Chris@102
|
265 "2: br 1b\n"
|
Chris@102
|
266 ".previous\n"
|
Chris@102
|
267
|
Chris@102
|
268 : "=&r" (original), // %0
|
Chris@102
|
269 "=&r" (modified) // %1
|
Chris@102
|
270 : "m" (storage), // %2
|
Chris@102
|
271 "r" (v) // %3
|
Chris@102
|
272 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
|
Chris@102
|
273 );
|
Chris@102
|
274 fence_after(order);
|
Chris@102
|
275 return original;
|
Chris@102
|
276 }
|
Chris@102
|
277
|
Chris@102
|
278 static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
279 {
|
Chris@102
|
280 storage_type original, modified;
|
Chris@102
|
281 fence_before(order);
|
Chris@102
|
282 __asm__ __volatile__
|
Chris@102
|
283 (
|
Chris@102
|
284 "1:\n"
|
Chris@102
|
285 "ldl_l %0, %2\n"
|
Chris@102
|
286 "bis %0, %3, %1\n"
|
Chris@102
|
287 "stl_c %1, %2\n"
|
Chris@102
|
288 "beq %1, 2f\n"
|
Chris@102
|
289
|
Chris@102
|
290 ".subsection 2\n"
|
Chris@102
|
291 "2: br 1b\n"
|
Chris@102
|
292 ".previous\n"
|
Chris@102
|
293
|
Chris@102
|
294 : "=&r" (original), // %0
|
Chris@102
|
295 "=&r" (modified) // %1
|
Chris@102
|
296 : "m" (storage), // %2
|
Chris@102
|
297 "r" (v) // %3
|
Chris@102
|
298 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
|
Chris@102
|
299 );
|
Chris@102
|
300 fence_after(order);
|
Chris@102
|
301 return original;
|
Chris@102
|
302 }
|
Chris@102
|
303
|
Chris@102
|
304 static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
305 {
|
Chris@102
|
306 storage_type original, modified;
|
Chris@102
|
307 fence_before(order);
|
Chris@102
|
308 __asm__ __volatile__
|
Chris@102
|
309 (
|
Chris@102
|
310 "1:\n"
|
Chris@102
|
311 "ldl_l %0, %2\n"
|
Chris@102
|
312 "xor %0, %3, %1\n"
|
Chris@102
|
313 "stl_c %1, %2\n"
|
Chris@102
|
314 "beq %1, 2f\n"
|
Chris@102
|
315
|
Chris@102
|
316 ".subsection 2\n"
|
Chris@102
|
317 "2: br 1b\n"
|
Chris@102
|
318 ".previous\n"
|
Chris@102
|
319
|
Chris@102
|
320 : "=&r" (original), // %0
|
Chris@102
|
321 "=&r" (modified) // %1
|
Chris@102
|
322 : "m" (storage), // %2
|
Chris@102
|
323 "r" (v) // %3
|
Chris@102
|
324 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
|
Chris@102
|
325 );
|
Chris@102
|
326 fence_after(order);
|
Chris@102
|
327 return original;
|
Chris@102
|
328 }
|
Chris@102
|
329
|
Chris@102
|
330 static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
331 {
|
Chris@102
|
332 return !!exchange(storage, (storage_type)1, order);
|
Chris@102
|
333 }
|
Chris@102
|
334
|
Chris@102
|
335 static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
336 {
|
Chris@102
|
337 store(storage, 0, order);
|
Chris@102
|
338 }
|
Chris@102
|
339
|
Chris@102
|
340 static BOOST_FORCEINLINE bool is_lock_free(storage_type const volatile&) BOOST_NOEXCEPT
|
Chris@102
|
341 {
|
Chris@102
|
342 return true;
|
Chris@102
|
343 }
|
Chris@102
|
344 };
|
Chris@102
|
345
|
Chris@102
|
346
|
Chris@102
|
347 template< >
|
Chris@102
|
348 struct operations< 1u, false > :
|
Chris@102
|
349 public operations< 4u, false >
|
Chris@102
|
350 {
|
Chris@102
|
351 typedef operations< 4u, false > base_type;
|
Chris@102
|
352 typedef base_type::storage_type storage_type;
|
Chris@102
|
353
|
Chris@102
|
354 static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
355 {
|
Chris@102
|
356 storage_type original, modified;
|
Chris@102
|
357 fence_before(order);
|
Chris@102
|
358 __asm__ __volatile__
|
Chris@102
|
359 (
|
Chris@102
|
360 "1:\n"
|
Chris@102
|
361 "ldl_l %0, %2\n"
|
Chris@102
|
362 "addl %0, %3, %1\n"
|
Chris@102
|
363 "zapnot %1, #1, %1\n"
|
Chris@102
|
364 "stl_c %1, %2\n"
|
Chris@102
|
365 "beq %1, 2f\n"
|
Chris@102
|
366
|
Chris@102
|
367 ".subsection 2\n"
|
Chris@102
|
368 "2: br 1b\n"
|
Chris@102
|
369 ".previous\n"
|
Chris@102
|
370
|
Chris@102
|
371 : "=&r" (original), // %0
|
Chris@102
|
372 "=&r" (modified) // %1
|
Chris@102
|
373 : "m" (storage), // %2
|
Chris@102
|
374 "r" (v) // %3
|
Chris@102
|
375 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
|
Chris@102
|
376 );
|
Chris@102
|
377 fence_after(order);
|
Chris@102
|
378 return original;
|
Chris@102
|
379 }
|
Chris@102
|
380
|
Chris@102
|
381 static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
382 {
|
Chris@102
|
383 storage_type original, modified;
|
Chris@102
|
384 fence_before(order);
|
Chris@102
|
385 __asm__ __volatile__
|
Chris@102
|
386 (
|
Chris@102
|
387 "1:\n"
|
Chris@102
|
388 "ldl_l %0, %2\n"
|
Chris@102
|
389 "subl %0, %3, %1\n"
|
Chris@102
|
390 "zapnot %1, #1, %1\n"
|
Chris@102
|
391 "stl_c %1, %2\n"
|
Chris@102
|
392 "beq %1, 2f\n"
|
Chris@102
|
393
|
Chris@102
|
394 ".subsection 2\n"
|
Chris@102
|
395 "2: br 1b\n"
|
Chris@102
|
396 ".previous\n"
|
Chris@102
|
397
|
Chris@102
|
398 : "=&r" (original), // %0
|
Chris@102
|
399 "=&r" (modified) // %1
|
Chris@102
|
400 : "m" (storage), // %2
|
Chris@102
|
401 "r" (v) // %3
|
Chris@102
|
402 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
|
Chris@102
|
403 );
|
Chris@102
|
404 fence_after(order);
|
Chris@102
|
405 return original;
|
Chris@102
|
406 }
|
Chris@102
|
407 };
|
Chris@102
|
408
|
Chris@102
|
409 template< >
|
Chris@102
|
410 struct operations< 1u, true > :
|
Chris@102
|
411 public operations< 4u, true >
|
Chris@102
|
412 {
|
Chris@102
|
413 typedef operations< 4u, true > base_type;
|
Chris@102
|
414 typedef base_type::storage_type storage_type;
|
Chris@102
|
415
|
Chris@102
|
416 static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
417 {
|
Chris@102
|
418 storage_type original, modified;
|
Chris@102
|
419 fence_before(order);
|
Chris@102
|
420 __asm__ __volatile__
|
Chris@102
|
421 (
|
Chris@102
|
422 "1:\n"
|
Chris@102
|
423 "ldl_l %0, %2\n"
|
Chris@102
|
424 "addl %0, %3, %1\n"
|
Chris@102
|
425 "sextb %1, %1\n"
|
Chris@102
|
426 "stl_c %1, %2\n"
|
Chris@102
|
427 "beq %1, 2f\n"
|
Chris@102
|
428
|
Chris@102
|
429 ".subsection 2\n"
|
Chris@102
|
430 "2: br 1b\n"
|
Chris@102
|
431 ".previous\n"
|
Chris@102
|
432
|
Chris@102
|
433 : "=&r" (original), // %0
|
Chris@102
|
434 "=&r" (modified) // %1
|
Chris@102
|
435 : "m" (storage), // %2
|
Chris@102
|
436 "r" (v) // %3
|
Chris@102
|
437 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
|
Chris@102
|
438 );
|
Chris@102
|
439 fence_after(order);
|
Chris@102
|
440 return original;
|
Chris@102
|
441 }
|
Chris@102
|
442
|
Chris@102
|
443 static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
444 {
|
Chris@102
|
445 storage_type original, modified;
|
Chris@102
|
446 fence_before(order);
|
Chris@102
|
447 __asm__ __volatile__
|
Chris@102
|
448 (
|
Chris@102
|
449 "1:\n"
|
Chris@102
|
450 "ldl_l %0, %2\n"
|
Chris@102
|
451 "subl %0, %3, %1\n"
|
Chris@102
|
452 "sextb %1, %1\n"
|
Chris@102
|
453 "stl_c %1, %2\n"
|
Chris@102
|
454 "beq %1, 2f\n"
|
Chris@102
|
455
|
Chris@102
|
456 ".subsection 2\n"
|
Chris@102
|
457 "2: br 1b\n"
|
Chris@102
|
458 ".previous\n"
|
Chris@102
|
459
|
Chris@102
|
460 : "=&r" (original), // %0
|
Chris@102
|
461 "=&r" (modified) // %1
|
Chris@102
|
462 : "m" (storage), // %2
|
Chris@102
|
463 "r" (v) // %3
|
Chris@102
|
464 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
|
Chris@102
|
465 );
|
Chris@102
|
466 fence_after(order);
|
Chris@102
|
467 return original;
|
Chris@102
|
468 }
|
Chris@102
|
469 };
|
Chris@102
|
470
|
Chris@102
|
471
|
Chris@102
|
472 template< >
|
Chris@102
|
473 struct operations< 2u, false > :
|
Chris@102
|
474 public operations< 4u, false >
|
Chris@102
|
475 {
|
Chris@102
|
476 typedef operations< 4u, false > base_type;
|
Chris@102
|
477 typedef base_type::storage_type storage_type;
|
Chris@102
|
478
|
Chris@102
|
479 static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
480 {
|
Chris@102
|
481 storage_type original, modified;
|
Chris@102
|
482 fence_before(order);
|
Chris@102
|
483 __asm__ __volatile__
|
Chris@102
|
484 (
|
Chris@102
|
485 "1:\n"
|
Chris@102
|
486 "ldl_l %0, %2\n"
|
Chris@102
|
487 "addl %0, %3, %1\n"
|
Chris@102
|
488 "zapnot %1, #3, %1\n"
|
Chris@102
|
489 "stl_c %1, %2\n"
|
Chris@102
|
490 "beq %1, 2f\n"
|
Chris@102
|
491
|
Chris@102
|
492 ".subsection 2\n"
|
Chris@102
|
493 "2: br 1b\n"
|
Chris@102
|
494 ".previous\n"
|
Chris@102
|
495
|
Chris@102
|
496 : "=&r" (original), // %0
|
Chris@102
|
497 "=&r" (modified) // %1
|
Chris@102
|
498 : "m" (storage), // %2
|
Chris@102
|
499 "r" (v) // %3
|
Chris@102
|
500 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
|
Chris@102
|
501 );
|
Chris@102
|
502 fence_after(order);
|
Chris@102
|
503 return original;
|
Chris@102
|
504 }
|
Chris@102
|
505
|
Chris@102
|
506 static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
507 {
|
Chris@102
|
508 storage_type original, modified;
|
Chris@102
|
509 fence_before(order);
|
Chris@102
|
510 __asm__ __volatile__
|
Chris@102
|
511 (
|
Chris@102
|
512 "1:\n"
|
Chris@102
|
513 "ldl_l %0, %2\n"
|
Chris@102
|
514 "subl %0, %3, %1\n"
|
Chris@102
|
515 "zapnot %1, #3, %1\n"
|
Chris@102
|
516 "stl_c %1, %2\n"
|
Chris@102
|
517 "beq %1, 2f\n"
|
Chris@102
|
518
|
Chris@102
|
519 ".subsection 2\n"
|
Chris@102
|
520 "2: br 1b\n"
|
Chris@102
|
521 ".previous\n"
|
Chris@102
|
522
|
Chris@102
|
523 : "=&r" (original), // %0
|
Chris@102
|
524 "=&r" (modified) // %1
|
Chris@102
|
525 : "m" (storage), // %2
|
Chris@102
|
526 "r" (v) // %3
|
Chris@102
|
527 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
|
Chris@102
|
528 );
|
Chris@102
|
529 fence_after(order);
|
Chris@102
|
530 return original;
|
Chris@102
|
531 }
|
Chris@102
|
532 };
|
Chris@102
|
533
|
Chris@102
|
534 template< >
|
Chris@102
|
535 struct operations< 2u, true > :
|
Chris@102
|
536 public operations< 4u, true >
|
Chris@102
|
537 {
|
Chris@102
|
538 typedef operations< 4u, true > base_type;
|
Chris@102
|
539 typedef base_type::storage_type storage_type;
|
Chris@102
|
540
|
Chris@102
|
541 static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
542 {
|
Chris@102
|
543 storage_type original, modified;
|
Chris@102
|
544 fence_before(order);
|
Chris@102
|
545 __asm__ __volatile__
|
Chris@102
|
546 (
|
Chris@102
|
547 "1:\n"
|
Chris@102
|
548 "ldl_l %0, %2\n"
|
Chris@102
|
549 "addl %0, %3, %1\n"
|
Chris@102
|
550 "sextw %1, %1\n"
|
Chris@102
|
551 "stl_c %1, %2\n"
|
Chris@102
|
552 "beq %1, 2f\n"
|
Chris@102
|
553
|
Chris@102
|
554 ".subsection 2\n"
|
Chris@102
|
555 "2: br 1b\n"
|
Chris@102
|
556 ".previous\n"
|
Chris@102
|
557
|
Chris@102
|
558 : "=&r" (original), // %0
|
Chris@102
|
559 "=&r" (modified) // %1
|
Chris@102
|
560 : "m" (storage), // %2
|
Chris@102
|
561 "r" (v) // %3
|
Chris@102
|
562 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
|
Chris@102
|
563 );
|
Chris@102
|
564 fence_after(order);
|
Chris@102
|
565 return original;
|
Chris@102
|
566 }
|
Chris@102
|
567
|
Chris@102
|
568 static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
569 {
|
Chris@102
|
570 storage_type original, modified;
|
Chris@102
|
571 fence_before(order);
|
Chris@102
|
572 __asm__ __volatile__
|
Chris@102
|
573 (
|
Chris@102
|
574 "1:\n"
|
Chris@102
|
575 "ldl_l %0, %2\n"
|
Chris@102
|
576 "subl %0, %3, %1\n"
|
Chris@102
|
577 "sextw %1, %1\n"
|
Chris@102
|
578 "stl_c %1, %2\n"
|
Chris@102
|
579 "beq %1, 2f\n"
|
Chris@102
|
580
|
Chris@102
|
581 ".subsection 2\n"
|
Chris@102
|
582 "2: br 1b\n"
|
Chris@102
|
583 ".previous\n"
|
Chris@102
|
584
|
Chris@102
|
585 : "=&r" (original), // %0
|
Chris@102
|
586 "=&r" (modified) // %1
|
Chris@102
|
587 : "m" (storage), // %2
|
Chris@102
|
588 "r" (v) // %3
|
Chris@102
|
589 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
|
Chris@102
|
590 );
|
Chris@102
|
591 fence_after(order);
|
Chris@102
|
592 return original;
|
Chris@102
|
593 }
|
Chris@102
|
594 };
|
Chris@102
|
595
|
Chris@102
|
596
|
Chris@102
|
597 template< bool Signed >
|
Chris@102
|
598 struct operations< 8u, Signed > :
|
Chris@102
|
599 public gcc_alpha_operations_base
|
Chris@102
|
600 {
|
Chris@102
|
601 typedef typename make_storage_type< 8u, Signed >::type storage_type;
|
Chris@102
|
602
|
Chris@102
|
603 static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
604 {
|
Chris@102
|
605 fence_before(order);
|
Chris@102
|
606 storage = v;
|
Chris@102
|
607 fence_after_store(order);
|
Chris@102
|
608 }
|
Chris@102
|
609
|
Chris@102
|
610 static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
611 {
|
Chris@102
|
612 storage_type v = storage;
|
Chris@102
|
613 fence_after(order);
|
Chris@102
|
614 return v;
|
Chris@102
|
615 }
|
Chris@102
|
616
|
Chris@102
|
617 static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
618 {
|
Chris@102
|
619 storage_type original, tmp;
|
Chris@102
|
620 fence_before(order);
|
Chris@102
|
621 __asm__ __volatile__
|
Chris@102
|
622 (
|
Chris@102
|
623 "1:\n"
|
Chris@102
|
624 "mov %3, %1\n"
|
Chris@102
|
625 "ldq_l %0, %2\n"
|
Chris@102
|
626 "stq_c %1, %2\n"
|
Chris@102
|
627 "beq %1, 2f\n"
|
Chris@102
|
628
|
Chris@102
|
629 ".subsection 2\n"
|
Chris@102
|
630 "2: br 1b\n"
|
Chris@102
|
631 ".previous\n"
|
Chris@102
|
632
|
Chris@102
|
633 : "=&r" (original), // %0
|
Chris@102
|
634 "=&r" (tmp) // %1
|
Chris@102
|
635 : "m" (storage), // %2
|
Chris@102
|
636 "r" (v) // %3
|
Chris@102
|
637 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
|
Chris@102
|
638 );
|
Chris@102
|
639 fence_after(order);
|
Chris@102
|
640 return original;
|
Chris@102
|
641 }
|
Chris@102
|
642
|
Chris@102
|
643 static BOOST_FORCEINLINE bool compare_exchange_weak(
|
Chris@102
|
644 storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
|
Chris@102
|
645 {
|
Chris@102
|
646 fence_before(success_order);
|
Chris@102
|
647 int success;
|
Chris@102
|
648 storage_type current;
|
Chris@102
|
649 __asm__ __volatile__
|
Chris@102
|
650 (
|
Chris@102
|
651 "1:\n"
|
Chris@102
|
652 "ldq_l %2, %4\n" // current = *(&storage)
|
Chris@102
|
653 "cmpeq %2, %0, %3\n" // success = current == expected
|
Chris@102
|
654 "mov %2, %0\n" // expected = current
|
Chris@102
|
655 "beq %3, 2f\n" // if (success == 0) goto end
|
Chris@102
|
656 "stq_c %1, %4\n" // storage = desired; desired = store succeeded
|
Chris@102
|
657 "mov %1, %3\n" // success = desired
|
Chris@102
|
658 "2:\n"
|
Chris@102
|
659 : "+&r" (expected), // %0
|
Chris@102
|
660 "+&r" (desired), // %1
|
Chris@102
|
661 "=&r" (current), // %2
|
Chris@102
|
662 "=&r" (success) // %3
|
Chris@102
|
663 : "m" (storage) // %4
|
Chris@102
|
664 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
|
Chris@102
|
665 );
|
Chris@102
|
666 if (success)
|
Chris@102
|
667 fence_after(success_order);
|
Chris@102
|
668 else
|
Chris@102
|
669 fence_after(failure_order);
|
Chris@102
|
670 return !!success;
|
Chris@102
|
671 }
|
Chris@102
|
672
|
Chris@102
|
673 static BOOST_FORCEINLINE bool compare_exchange_strong(
|
Chris@102
|
674 storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
|
Chris@102
|
675 {
|
Chris@102
|
676 int success;
|
Chris@102
|
677 storage_type current, tmp;
|
Chris@102
|
678 fence_before(success_order);
|
Chris@102
|
679 __asm__ __volatile__
|
Chris@102
|
680 (
|
Chris@102
|
681 "1:\n"
|
Chris@102
|
682 "mov %5, %1\n" // tmp = desired
|
Chris@102
|
683 "ldq_l %2, %4\n" // current = *(&storage)
|
Chris@102
|
684 "cmpeq %2, %0, %3\n" // success = current == expected
|
Chris@102
|
685 "mov %2, %0\n" // expected = current
|
Chris@102
|
686 "beq %3, 2f\n" // if (success == 0) goto end
|
Chris@102
|
687 "stq_c %1, %4\n" // storage = tmp; tmp = store succeeded
|
Chris@102
|
688 "beq %1, 3f\n" // if (tmp == 0) goto retry
|
Chris@102
|
689 "mov %1, %3\n" // success = tmp
|
Chris@102
|
690 "2:\n"
|
Chris@102
|
691
|
Chris@102
|
692 ".subsection 2\n"
|
Chris@102
|
693 "3: br 1b\n"
|
Chris@102
|
694 ".previous\n"
|
Chris@102
|
695
|
Chris@102
|
696 : "+&r" (expected), // %0
|
Chris@102
|
697 "=&r" (tmp), // %1
|
Chris@102
|
698 "=&r" (current), // %2
|
Chris@102
|
699 "=&r" (success) // %3
|
Chris@102
|
700 : "m" (storage), // %4
|
Chris@102
|
701 "r" (desired) // %5
|
Chris@102
|
702 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
|
Chris@102
|
703 );
|
Chris@102
|
704 if (success)
|
Chris@102
|
705 fence_after(success_order);
|
Chris@102
|
706 else
|
Chris@102
|
707 fence_after(failure_order);
|
Chris@102
|
708 return !!success;
|
Chris@102
|
709 }
|
Chris@102
|
710
|
Chris@102
|
711 static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
712 {
|
Chris@102
|
713 storage_type original, modified;
|
Chris@102
|
714 fence_before(order);
|
Chris@102
|
715 __asm__ __volatile__
|
Chris@102
|
716 (
|
Chris@102
|
717 "1:\n"
|
Chris@102
|
718 "ldq_l %0, %2\n"
|
Chris@102
|
719 "addq %0, %3, %1\n"
|
Chris@102
|
720 "stq_c %1, %2\n"
|
Chris@102
|
721 "beq %1, 2f\n"
|
Chris@102
|
722
|
Chris@102
|
723 ".subsection 2\n"
|
Chris@102
|
724 "2: br 1b\n"
|
Chris@102
|
725 ".previous\n"
|
Chris@102
|
726
|
Chris@102
|
727 : "=&r" (original), // %0
|
Chris@102
|
728 "=&r" (modified) // %1
|
Chris@102
|
729 : "m" (storage), // %2
|
Chris@102
|
730 "r" (v) // %3
|
Chris@102
|
731 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
|
Chris@102
|
732 );
|
Chris@102
|
733 fence_after(order);
|
Chris@102
|
734 return original;
|
Chris@102
|
735 }
|
Chris@102
|
736
|
Chris@102
|
737 static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
738 {
|
Chris@102
|
739 storage_type original, modified;
|
Chris@102
|
740 fence_before(order);
|
Chris@102
|
741 __asm__ __volatile__
|
Chris@102
|
742 (
|
Chris@102
|
743 "1:\n"
|
Chris@102
|
744 "ldq_l %0, %2\n"
|
Chris@102
|
745 "subq %0, %3, %1\n"
|
Chris@102
|
746 "stq_c %1, %2\n"
|
Chris@102
|
747 "beq %1, 2f\n"
|
Chris@102
|
748
|
Chris@102
|
749 ".subsection 2\n"
|
Chris@102
|
750 "2: br 1b\n"
|
Chris@102
|
751 ".previous\n"
|
Chris@102
|
752
|
Chris@102
|
753 : "=&r" (original), // %0
|
Chris@102
|
754 "=&r" (modified) // %1
|
Chris@102
|
755 : "m" (storage), // %2
|
Chris@102
|
756 "r" (v) // %3
|
Chris@102
|
757 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
|
Chris@102
|
758 );
|
Chris@102
|
759 fence_after(order);
|
Chris@102
|
760 return original;
|
Chris@102
|
761 }
|
Chris@102
|
762
|
Chris@102
|
763 static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
764 {
|
Chris@102
|
765 storage_type original, modified;
|
Chris@102
|
766 fence_before(order);
|
Chris@102
|
767 __asm__ __volatile__
|
Chris@102
|
768 (
|
Chris@102
|
769 "1:\n"
|
Chris@102
|
770 "ldq_l %0, %2\n"
|
Chris@102
|
771 "and %0, %3, %1\n"
|
Chris@102
|
772 "stq_c %1, %2\n"
|
Chris@102
|
773 "beq %1, 2f\n"
|
Chris@102
|
774
|
Chris@102
|
775 ".subsection 2\n"
|
Chris@102
|
776 "2: br 1b\n"
|
Chris@102
|
777 ".previous\n"
|
Chris@102
|
778
|
Chris@102
|
779 : "=&r" (original), // %0
|
Chris@102
|
780 "=&r" (modified) // %1
|
Chris@102
|
781 : "m" (storage), // %2
|
Chris@102
|
782 "r" (v) // %3
|
Chris@102
|
783 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
|
Chris@102
|
784 );
|
Chris@102
|
785 fence_after(order);
|
Chris@102
|
786 return original;
|
Chris@102
|
787 }
|
Chris@102
|
788
|
Chris@102
|
789 static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
790 {
|
Chris@102
|
791 storage_type original, modified;
|
Chris@102
|
792 fence_before(order);
|
Chris@102
|
793 __asm__ __volatile__
|
Chris@102
|
794 (
|
Chris@102
|
795 "1:\n"
|
Chris@102
|
796 "ldq_l %0, %2\n"
|
Chris@102
|
797 "bis %0, %3, %1\n"
|
Chris@102
|
798 "stq_c %1, %2\n"
|
Chris@102
|
799 "beq %1, 2f\n"
|
Chris@102
|
800
|
Chris@102
|
801 ".subsection 2\n"
|
Chris@102
|
802 "2: br 1b\n"
|
Chris@102
|
803 ".previous\n"
|
Chris@102
|
804
|
Chris@102
|
805 : "=&r" (original), // %0
|
Chris@102
|
806 "=&r" (modified) // %1
|
Chris@102
|
807 : "m" (storage), // %2
|
Chris@102
|
808 "r" (v) // %3
|
Chris@102
|
809 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
|
Chris@102
|
810 );
|
Chris@102
|
811 fence_after(order);
|
Chris@102
|
812 return original;
|
Chris@102
|
813 }
|
Chris@102
|
814
|
Chris@102
|
815 static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
816 {
|
Chris@102
|
817 storage_type original, modified;
|
Chris@102
|
818 fence_before(order);
|
Chris@102
|
819 __asm__ __volatile__
|
Chris@102
|
820 (
|
Chris@102
|
821 "1:\n"
|
Chris@102
|
822 "ldq_l %0, %2\n"
|
Chris@102
|
823 "xor %0, %3, %1\n"
|
Chris@102
|
824 "stq_c %1, %2\n"
|
Chris@102
|
825 "beq %1, 2f\n"
|
Chris@102
|
826
|
Chris@102
|
827 ".subsection 2\n"
|
Chris@102
|
828 "2: br 1b\n"
|
Chris@102
|
829 ".previous\n"
|
Chris@102
|
830
|
Chris@102
|
831 : "=&r" (original), // %0
|
Chris@102
|
832 "=&r" (modified) // %1
|
Chris@102
|
833 : "m" (storage), // %2
|
Chris@102
|
834 "r" (v) // %3
|
Chris@102
|
835 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
|
Chris@102
|
836 );
|
Chris@102
|
837 fence_after(order);
|
Chris@102
|
838 return original;
|
Chris@102
|
839 }
|
Chris@102
|
840
|
Chris@102
|
841 static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
842 {
|
Chris@102
|
843 return !!exchange(storage, (storage_type)1, order);
|
Chris@102
|
844 }
|
Chris@102
|
845
|
Chris@102
|
846 static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
847 {
|
Chris@102
|
848 store(storage, 0, order);
|
Chris@102
|
849 }
|
Chris@102
|
850
|
Chris@102
|
851 static BOOST_FORCEINLINE bool is_lock_free(storage_type const volatile&) BOOST_NOEXCEPT
|
Chris@102
|
852 {
|
Chris@102
|
853 return true;
|
Chris@102
|
854 }
|
Chris@102
|
855 };
|
Chris@102
|
856
|
Chris@102
|
857
|
Chris@102
|
858 BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
859 {
|
Chris@102
|
860 if (order != memory_order_relaxed)
|
Chris@102
|
861 __asm__ __volatile__ ("mb" ::: "memory");
|
Chris@102
|
862 }
|
Chris@102
|
863
|
Chris@102
|
864 BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
865 {
|
Chris@102
|
866 if (order != memory_order_relaxed)
|
Chris@102
|
867 __asm__ __volatile__ ("" ::: "memory");
|
Chris@102
|
868 }
|
Chris@102
|
869
|
Chris@102
|
870 } // namespace detail
|
Chris@102
|
871 } // namespace atomics
|
Chris@102
|
872 } // namespace boost
|
Chris@102
|
873
|
Chris@102
|
874 #endif // BOOST_ATOMIC_DETAIL_OPS_GCC_ALPHA_HPP_INCLUDED_
|