]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/c_global/cstdatomic
re PR testsuite/39696 (gcc.dg/tree-ssa/ssa-ccp-25.c scan-tree-dump doesn't work on...
[thirdparty/gcc.git] / libstdc++-v3 / include / c_global / cstdatomic
CommitLineData
d466a7e2
BK
1// -*- C++ -*- header.
2
5b9daa7e 3// Copyright (C) 2008, 2009
d466a7e2
BK
4// Free Software Foundation, Inc.
5//
6// This file is part of the GNU ISO C++ Library. This library is free
7// software; you can redistribute it and/or modify it under the
8// terms of the GNU General Public License as published by the
9// Free Software Foundation; either version 2, or (at your option)
10// any later version.
11
12// This library is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15// GNU General Public License for more details.
16
17// You should have received a copy of the GNU General Public License
18// along with this library; see the file COPYING. If not, write to
19// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
20// Boston, MA 02110-1301, USA.
21
22// As a special exception, you may use this file as part of a free software
23// library without restriction. Specifically, if other files instantiate
24// templates or use macros or inline functions from this file, or you compile
25// this file and link it with other files to produce an executable, this
26// file does not by itself cause the resulting executable to be covered by
27// the GNU General Public License. This exception does not however
28// invalidate any other reasons why the executable file might be covered by
29// the GNU General Public License.
30
31/** @file cstdatomic
32 * This is a Standard C++ Library file. You should @c #include this file
33 * in your programs, rather than any of the "*.h" implementation files.
34 *
35 * This is the C++ version of the Standard C Library header @c stdatomic.h,
36 * and its contents are (mostly) the same as that header, but are all
37 * contained in the namespace @c std (except for names which are defined
38 * as macros in C).
39 */
40
41// Based on "C++ Atomic Types and Operations" by Hans Boehm and Lawrence Crowl.
42// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html
43
44#ifndef _GLIBCXX_STDATOMIC
45#define _GLIBCXX_STDATOMIC 1
46
47#pragma GCC system_header
48
49#ifndef __GXX_EXPERIMENTAL_CXX0X__
50# include <c++0x_warning.h>
51#endif
52
53#include <stdatomic.h>
54#include <cstddef>
55
56_GLIBCXX_BEGIN_NAMESPACE(std)
57
5b9daa7e
BK
58 /**
59 * @addtogroup atomics
60 * @{
61 */
62
50ce8d3d
BK
63 /// kill_dependency
64 template<typename _Tp>
65 inline _Tp
66 kill_dependency(_Tp __y)
67 {
68 _Tp ret(__y);
69 return ret;
70 }
d466a7e2 71
50ce8d3d
BK
72 inline memory_order
73 __calculate_memory_order(memory_order __m)
d466a7e2 74 {
50ce8d3d
BK
75 const bool __cond1 = __m == memory_order_release;
76 const bool __cond2 = __m == memory_order_acq_rel;
77 memory_order __mo1(__cond1 ? memory_order_relaxed : __m);
d466a7e2 78 memory_order __mo2(__cond2 ? memory_order_acquire : __mo1);
50ce8d3d 79 return __mo2;
d466a7e2
BK
80 }
81
50ce8d3d
BK
82 //
83 // Three nested namespaces for atomic implementation details.
84 //
85 // The nested namespace inlined into std:: is determined by the value
86 // of the _GLIBCXX_ATOMIC_PROPERTY macro and the resulting
87 // ATOMIC_*_LOCK_FREE macros. See file stdatomic.h.
88 //
89 // 0 == __atomic0 == Never lock-free
90 // 1 == __atomic1 == Best available, sometimes lock-free
91 // 2 == __atomic2 == Always lock-free
92#include <bits/atomic_0.h>
93#include <bits/atomic_2.h>
d466a7e2 94
50ce8d3d
BK
95 /// atomic
96 /// 29.4.3, Generic atomic type, primary class template.
97 template<typename _Tp>
98 struct atomic
99 {
100 private:
101 _Tp _M_i;
d466a7e2 102
50ce8d3d
BK
103 public:
104 atomic() = default;
105 ~atomic() = default;
106 atomic(const atomic&) = delete;
107 atomic& operator=(const atomic&) = delete;
d466a7e2 108
50ce8d3d 109 atomic(_Tp __i) : _M_i(__i) { }
d466a7e2 110
50ce8d3d 111 operator _Tp() const volatile;
d466a7e2 112
50ce8d3d
BK
113 _Tp
114 operator=(_Tp __i) volatile { store(__i); return __i; }
d466a7e2 115
50ce8d3d
BK
116 bool
117 is_lock_free() const volatile;
d466a7e2 118
50ce8d3d
BK
119 void
120 store(_Tp, memory_order = memory_order_seq_cst) volatile;
d466a7e2 121
50ce8d3d
BK
122 _Tp
123 load(memory_order = memory_order_seq_cst) const volatile;
d466a7e2 124
50ce8d3d
BK
125 _Tp
126 exchange(_Tp __i, memory_order = memory_order_seq_cst) volatile;
d466a7e2 127
50ce8d3d
BK
128 bool
129 compare_exchange_weak(_Tp&, _Tp, memory_order, memory_order) volatile;
d466a7e2 130
50ce8d3d
BK
131 bool
132 compare_exchange_strong(_Tp&, _Tp, memory_order, memory_order) volatile;
d466a7e2 133
50ce8d3d
BK
134 bool
135 compare_exchange_weak(_Tp&, _Tp,
136 memory_order = memory_order_seq_cst) volatile;
d466a7e2 137
50ce8d3d
BK
138 bool
139 compare_exchange_strong(_Tp&, _Tp,
140 memory_order = memory_order_seq_cst) volatile;
141 };
d466a7e2 142
d466a7e2 143
50ce8d3d
BK
144 /// Partial specialization for pointer types.
145 template<typename _Tp>
146 struct atomic<_Tp*> : atomic_address
147 {
148 atomic() = default;
149 ~atomic() = default;
150 atomic(const atomic&) = delete;
151 atomic& operator=(const atomic&) = delete;
d466a7e2 152
50ce8d3d 153 atomic(_Tp* __v) : atomic_address(__v) { }
d466a7e2 154
50ce8d3d
BK
155 void
156 store(_Tp*, memory_order = memory_order_seq_cst) volatile;
d466a7e2 157
50ce8d3d
BK
158 _Tp*
159 load(memory_order = memory_order_seq_cst) const volatile;
d466a7e2 160
50ce8d3d
BK
161 _Tp*
162 exchange(_Tp*, memory_order = memory_order_seq_cst) volatile;
d466a7e2 163
50ce8d3d
BK
164 bool
165 compare_exchange_weak(_Tp*&, _Tp*, memory_order, memory_order) volatile;
d466a7e2 166
50ce8d3d
BK
167 bool
168 compare_exchange_strong(_Tp*&, _Tp*, memory_order, memory_order) volatile;
d466a7e2 169
50ce8d3d
BK
170 bool
171 compare_exchange_weak(_Tp*&, _Tp*,
172 memory_order = memory_order_seq_cst) volatile;
d466a7e2 173
50ce8d3d
BK
174 bool
175 compare_exchange_strong(_Tp*&, _Tp*,
176 memory_order = memory_order_seq_cst) volatile;
d466a7e2 177
50ce8d3d
BK
178 _Tp*
179 fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst) volatile;
d466a7e2 180
50ce8d3d
BK
181 _Tp*
182 fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst) volatile;
d466a7e2 183
50ce8d3d
BK
184 operator _Tp*() const volatile
185 { return load(); }
d466a7e2 186
50ce8d3d
BK
187 _Tp*
188 operator=(_Tp* __v) volatile
189 {
190 store(__v);
191 return __v;
192 }
d466a7e2 193
50ce8d3d
BK
194 _Tp*
195 operator++(int) volatile { return fetch_add(1); }
d466a7e2 196
50ce8d3d
BK
197 _Tp*
198 operator--(int) volatile { return fetch_sub(1); }
d466a7e2 199
50ce8d3d
BK
200 _Tp*
201 operator++() volatile { return fetch_add(1) + 1; }
d466a7e2 202
50ce8d3d
BK
203 _Tp*
204 operator--() volatile { return fetch_sub(1) - 1; }
d466a7e2 205
50ce8d3d
BK
206 _Tp*
207 operator+=(ptrdiff_t __d) volatile
208 { return fetch_add(__d) + __d; }
d466a7e2 209
50ce8d3d
BK
210 _Tp*
211 operator-=(ptrdiff_t __d) volatile
212 { return fetch_sub(__d) - __d; }
213 };
d466a7e2 214
d466a7e2 215
50ce8d3d
BK
216 /// Explicit specialization for void*
217 template<>
218 struct atomic<void*> : public atomic_address
219 {
220 typedef void* __integral_type;
221 typedef atomic_address __base_type;
d466a7e2 222
50ce8d3d
BK
223 atomic() = default;
224 ~atomic() = default;
225 atomic(const atomic&) = delete;
226 atomic& operator=(const atomic&) = delete;
d466a7e2 227
50ce8d3d 228 atomic(__integral_type __i) : __base_type(__i) { }
d466a7e2 229
50ce8d3d
BK
230 using __base_type::operator __integral_type;
231 using __base_type::operator=;
232 };
d466a7e2 233
50ce8d3d
BK
234 /// Explicit specialization for bool.
235 template<>
236 struct atomic<bool> : public atomic_bool
237 {
238 typedef bool __integral_type;
239 typedef atomic_bool __base_type;
d466a7e2 240
50ce8d3d
BK
241 atomic() = default;
242 ~atomic() = default;
243 atomic(const atomic&) = delete;
244 atomic& operator=(const atomic&) = delete;
d466a7e2 245
50ce8d3d 246 atomic(__integral_type __i) : __base_type(__i) { }
d466a7e2 247
50ce8d3d
BK
248 using __base_type::operator __integral_type;
249 using __base_type::operator=;
250 };
d466a7e2 251
50ce8d3d
BK
252 /// Explicit specialization for char.
253 template<>
254 struct atomic<char> : public atomic_char
255 {
256 typedef char __integral_type;
257 typedef atomic_char __base_type;
d466a7e2 258
50ce8d3d
BK
259 atomic() = default;
260 ~atomic() = default;
261 atomic(const atomic&) = delete;
262 atomic& operator=(const atomic&) = delete;
d466a7e2 263
50ce8d3d 264 atomic(__integral_type __i) : __base_type(__i) { }
d466a7e2 265
50ce8d3d
BK
266 using __base_type::operator __integral_type;
267 using __base_type::operator=;
268 };
d466a7e2 269
50ce8d3d
BK
270 /// Explicit specialization for signed char.
271 template<>
272 struct atomic<signed char> : public atomic_schar
273 {
274 typedef signed char __integral_type;
275 typedef atomic_schar __base_type;
d466a7e2 276
50ce8d3d
BK
277 atomic() = default;
278 ~atomic() = default;
279 atomic(const atomic&) = delete;
280 atomic& operator=(const atomic&) = delete;
d466a7e2 281
50ce8d3d 282 atomic(__integral_type __i) : __base_type(__i) { }
d466a7e2 283
50ce8d3d
BK
284 using __base_type::operator __integral_type;
285 using __base_type::operator=;
286 };
d466a7e2 287
50ce8d3d
BK
288 /// Explicit specialization for unsigned char.
289 template<>
290 struct atomic<unsigned char> : public atomic_uchar
291 {
292 typedef unsigned char __integral_type;
293 typedef atomic_uchar __base_type;
d466a7e2 294
50ce8d3d
BK
295 atomic() = default;
296 ~atomic() = default;
297 atomic(const atomic&) = delete;
298 atomic& operator=(const atomic&) = delete;
d466a7e2 299
50ce8d3d 300 atomic(__integral_type __i) : __base_type(__i) { }
d466a7e2 301
50ce8d3d
BK
302 using __base_type::operator __integral_type;
303 using __base_type::operator=;
304 };
d466a7e2 305
50ce8d3d
BK
306 /// Explicit specialization for short.
307 template<>
308 struct atomic<short> : public atomic_short
309 {
310 typedef short __integral_type;
311 typedef atomic_short __base_type;
d466a7e2 312
50ce8d3d
BK
313 atomic() = default;
314 ~atomic() = default;
315 atomic(const atomic&) = delete;
316 atomic& operator=(const atomic&) = delete;
d466a7e2 317
50ce8d3d 318 atomic(__integral_type __i) : __base_type(__i) { }
d466a7e2 319
50ce8d3d
BK
320 using __base_type::operator __integral_type;
321 using __base_type::operator=;
322 };
d466a7e2 323
50ce8d3d
BK
324 /// Explicit specialization for unsigned short.
325 template<>
326 struct atomic<unsigned short> : public atomic_ushort
327 {
328 typedef unsigned short __integral_type;
329 typedef atomic_ushort __base_type;
d466a7e2 330
50ce8d3d
BK
331 atomic() = default;
332 ~atomic() = default;
333 atomic(const atomic&) = delete;
334 atomic& operator=(const atomic&) = delete;
d466a7e2 335
50ce8d3d 336 atomic(__integral_type __i) : __base_type(__i) { }
d466a7e2 337
50ce8d3d
BK
338 using __base_type::operator __integral_type;
339 using __base_type::operator=;
340 };
d466a7e2 341
50ce8d3d
BK
342 /// Explicit specialization for int.
343 template<>
344 struct atomic<int> : atomic_int
345 {
346 typedef int __integral_type;
347 typedef atomic_int __base_type;
d466a7e2 348
50ce8d3d
BK
349 atomic() = default;
350 ~atomic() = default;
351 atomic(const atomic&) = delete;
352 atomic& operator=(const atomic&) = delete;
d466a7e2 353
50ce8d3d 354 atomic(__integral_type __i) : __base_type(__i) { }
d466a7e2 355
50ce8d3d
BK
356 using __base_type::operator __integral_type;
357 using __base_type::operator=;
358 };
d466a7e2 359
50ce8d3d
BK
360 /// Explicit specialization for unsigned int.
361 template<>
362 struct atomic<unsigned int> : public atomic_uint
363 {
364 typedef unsigned int __integral_type;
365 typedef atomic_uint __base_type;
d466a7e2 366
50ce8d3d
BK
367 atomic() = default;
368 ~atomic() = default;
369 atomic(const atomic&) = delete;
370 atomic& operator=(const atomic&) = delete;
d466a7e2 371
50ce8d3d 372 atomic(__integral_type __i) : __base_type(__i) { }
d466a7e2 373
50ce8d3d
BK
374 using __base_type::operator __integral_type;
375 using __base_type::operator=;
376 };
d466a7e2 377
50ce8d3d
BK
378 /// Explicit specialization for long.
379 template<>
380 struct atomic<long> : public atomic_long
381 {
382 typedef long __integral_type;
383 typedef atomic_long __base_type;
d466a7e2 384
50ce8d3d
BK
385 atomic() = default;
386 ~atomic() = default;
387 atomic(const atomic&) = delete;
388 atomic& operator=(const atomic&) = delete;
d466a7e2 389
50ce8d3d 390 atomic(__integral_type __i) : __base_type(__i) { }
d466a7e2 391
50ce8d3d
BK
392 using __base_type::operator __integral_type;
393 using __base_type::operator=;
394 };
d466a7e2 395
50ce8d3d
BK
396 /// Explicit specialization for unsigned long.
397 template<>
398 struct atomic<unsigned long> : public atomic_ulong
399 {
400 typedef unsigned long __integral_type;
401 typedef atomic_ulong __base_type;
d466a7e2 402
50ce8d3d
BK
403 atomic() = default;
404 ~atomic() = default;
405 atomic(const atomic&) = delete;
406 atomic& operator=(const atomic&) = delete;
d466a7e2 407
50ce8d3d 408 atomic(__integral_type __i) : __base_type(__i) { }
d466a7e2 409
50ce8d3d
BK
410 using __base_type::operator __integral_type;
411 using __base_type::operator=;
412 };
d466a7e2 413
50ce8d3d
BK
414 /// Explicit specialization for long long.
415 template<>
416 struct atomic<long long> : public atomic_llong
417 {
418 typedef long long __integral_type;
419 typedef atomic_llong __base_type;
d466a7e2 420
50ce8d3d
BK
421 atomic() = default;
422 ~atomic() = default;
423 atomic(const atomic&) = delete;
424 atomic& operator=(const atomic&) = delete;
d466a7e2 425
50ce8d3d 426 atomic(__integral_type __i) : __base_type(__i) { }
d466a7e2 427
50ce8d3d
BK
428 using __base_type::operator __integral_type;
429 using __base_type::operator=;
430 };
d466a7e2 431
50ce8d3d
BK
432 /// Explicit specialization for unsigned long long.
433 template<>
434 struct atomic<unsigned long long> : public atomic_ullong
435 {
436 typedef unsigned long long __integral_type;
437 typedef atomic_ullong __base_type;
d466a7e2 438
50ce8d3d
BK
439 atomic() = default;
440 ~atomic() = default;
441 atomic(const atomic&) = delete;
442 atomic& operator=(const atomic&) = delete;
d466a7e2 443
50ce8d3d 444 atomic(__integral_type __i) : __base_type(__i) { }
d466a7e2 445
50ce8d3d
BK
446 using __base_type::operator __integral_type;
447 using __base_type::operator=;
448 };
d466a7e2 449
50ce8d3d
BK
450 /// Explicit specialization for wchar_t.
451 template<>
452 struct atomic<wchar_t> : public atomic_wchar_t
453 {
454 typedef wchar_t __integral_type;
455 typedef atomic_wchar_t __base_type;
d466a7e2 456
50ce8d3d
BK
457 atomic() = default;
458 ~atomic() = default;
459 atomic(const atomic&) = delete;
460 atomic& operator=(const atomic&) = delete;
d466a7e2 461
50ce8d3d 462 atomic(__integral_type __i) : __base_type(__i) { }
d466a7e2 463
50ce8d3d
BK
464 using __base_type::operator __integral_type;
465 using __base_type::operator=;
466 };
d466a7e2 467
50ce8d3d
BK
468 /// Explicit specialization for char16_t.
469 template<>
470 struct atomic<char16_t> : public atomic_char16_t
471 {
472 typedef char16_t __integral_type;
473 typedef atomic_char16_t __base_type;
d466a7e2 474
50ce8d3d
BK
475 atomic() = default;
476 ~atomic() = default;
477 atomic(const atomic&) = delete;
478 atomic& operator=(const atomic&) = delete;
d466a7e2 479
50ce8d3d 480 atomic(__integral_type __i) : __base_type(__i) { }
d466a7e2 481
50ce8d3d
BK
482 using __base_type::operator __integral_type;
483 using __base_type::operator=;
484 };
d466a7e2 485
50ce8d3d
BK
486 /// Explicit specialization for char32_t.
487 template<>
488 struct atomic<char32_t> : public atomic_char32_t
489 {
490 typedef char32_t __integral_type;
491 typedef atomic_char32_t __base_type;
d466a7e2 492
50ce8d3d
BK
493 atomic() = default;
494 ~atomic() = default;
495 atomic(const atomic&) = delete;
496 atomic& operator=(const atomic&) = delete;
d466a7e2 497
50ce8d3d 498 atomic(__integral_type __i) : __base_type(__i) { }
d466a7e2 499
50ce8d3d
BK
500 using __base_type::operator __integral_type;
501 using __base_type::operator=;
502 };
d466a7e2
BK
503
504
50ce8d3d
BK
505 template<typename _Tp>
506 _Tp*
507 atomic<_Tp*>::load(memory_order __m) const volatile
508 { return static_cast<_Tp*>(atomic_address::load(__m)); }
d466a7e2 509
50ce8d3d
BK
510 template<typename _Tp>
511 _Tp*
512 atomic<_Tp*>::exchange(_Tp* __v, memory_order __m) volatile
513 { return static_cast<_Tp*>(atomic_address::exchange(__v, __m)); }
d466a7e2 514
50ce8d3d
BK
515 template<typename _Tp>
516 bool
517 atomic<_Tp*>::compare_exchange_weak(_Tp*& __r, _Tp* __v, memory_order __m1,
518 memory_order __m2) volatile
519 {
520 void** __vr = reinterpret_cast<void**>(&__r);
521 void* __vv = static_cast<void*>(__v);
522 return atomic_address::compare_exchange_weak(*__vr, __vv, __m1, __m2);
523 }
d466a7e2 524
50ce8d3d
BK
525 template<typename _Tp>
526 bool
527 atomic<_Tp*>::compare_exchange_strong(_Tp*& __r, _Tp* __v,
528 memory_order __m1,
529 memory_order __m2) volatile
530 {
531 void** __vr = reinterpret_cast<void**>(&__r);
532 void* __vv = static_cast<void*>(__v);
533 return atomic_address::compare_exchange_strong(*__vr, __vv, __m1, __m2);
534 }
d466a7e2 535
50ce8d3d
BK
536 template<typename _Tp>
537 bool
538 atomic<_Tp*>::compare_exchange_weak(_Tp*& __r, _Tp* __v,
539 memory_order __m) volatile
540 {
541 return compare_exchange_weak(__r, __v, __m,
542 __calculate_memory_order(__m));
543 }
d466a7e2 544
50ce8d3d
BK
545 template<typename _Tp>
546 bool
547 atomic<_Tp*>::compare_exchange_strong(_Tp*& __r, _Tp* __v,
548 memory_order __m) volatile
549 {
550 return compare_exchange_strong(__r, __v, __m,
551 __calculate_memory_order(__m));
552 }
d466a7e2 553
50ce8d3d
BK
554 template<typename _Tp>
555 _Tp*
556 atomic<_Tp*>::fetch_add(ptrdiff_t __d, memory_order __m) volatile
557 {
558 void* __p = atomic_fetch_add_explicit(this, sizeof(_Tp) * __d, __m);
559 return static_cast<_Tp*>(__p);
560 }
d466a7e2 561
50ce8d3d
BK
562 template<typename _Tp>
563 _Tp*
564 atomic<_Tp*>::fetch_sub(ptrdiff_t __d, memory_order __m) volatile
565 {
566 void* __p = atomic_fetch_sub_explicit(this, sizeof(_Tp) * __d, __m);
567 return static_cast<_Tp*>(__p);
568 }
d466a7e2 569
50ce8d3d
BK
570 // Convenience function definitions, atomic_flag.
571 inline bool
572 atomic_flag_test_and_set_explicit(volatile atomic_flag* __a, memory_order __m)
573 { return __a->test_and_set(__m); }
d466a7e2 574
50ce8d3d
BK
575 inline void
576 atomic_flag_clear_explicit(volatile atomic_flag* __a, memory_order __m)
577 { return __a->clear(__m); }
d466a7e2 578
d466a7e2 579
50ce8d3d
BK
580 // Convenience function definitions, atomic_address.
581 inline bool
582 atomic_is_lock_free(const volatile atomic_address* __a)
583 { return __a->is_lock_free(); }
d466a7e2 584
50ce8d3d
BK
585 inline void
586 atomic_store(volatile atomic_address* __a, void* __v)
587 { __a->store(__v); }
d466a7e2 588
50ce8d3d
BK
589 inline void
590 atomic_store_explicit(volatile atomic_address* __a, void* __v,
591 memory_order __m)
592 { __a->store(__v, __m); }
d466a7e2 593
50ce8d3d
BK
594 inline void*
595 atomic_load(const volatile atomic_address* __a)
596 { return __a->load(); }
d466a7e2 597
50ce8d3d
BK
598 inline void*
599 atomic_load_explicit(const volatile atomic_address* __a, memory_order __m)
600 { return __a->load(__m); }
d466a7e2 601
50ce8d3d
BK
602 inline void*
603 atomic_exchange(volatile atomic_address* __a, void* __v)
604 { return __a->exchange(__v); }
d466a7e2 605
50ce8d3d
BK
606 inline void*
607 atomic_exchange_explicit(volatile atomic_address* __a, void* __v,
608 memory_order __m)
609 { return __a->exchange(__v, __m); }
d466a7e2 610
50ce8d3d
BK
611 inline bool
612 atomic_compare_exchange_weak(volatile atomic_address* __a,
613 void** __v1, void* __v2)
614 {
615 return __a->compare_exchange_weak(*__v1, __v2, memory_order_seq_cst,
616 memory_order_seq_cst);
617 }
d466a7e2 618
50ce8d3d
BK
619 inline bool
620 atomic_compare_exchange_strong(volatile atomic_address* __a,
621 void** __v1, void* __v2)
622 {
623 return __a->compare_exchange_strong(*__v1, __v2, memory_order_seq_cst,
624 memory_order_seq_cst);
625 }
d466a7e2 626
50ce8d3d
BK
627 inline bool
628 atomic_compare_exchange_weak_explicit(volatile atomic_address* __a,
629 void** __v1, void* __v2,
630 memory_order __m1, memory_order __m2)
631 { return __a->compare_exchange_weak(*__v1, __v2, __m1, __m2); }
d466a7e2 632
50ce8d3d
BK
633 inline bool
634 atomic_compare_exchange_strong_explicit(volatile atomic_address* __a,
635 void** __v1, void* __v2,
636 memory_order __m1, memory_order __m2)
637 { return __a->compare_exchange_strong(*__v1, __v2, __m1, __m2); }
d466a7e2 638
50ce8d3d
BK
639 inline void*
640 atomic_fetch_add_explicit(volatile atomic_address* __a, ptrdiff_t __d,
641 memory_order __m)
642 { return __a->fetch_add(__d, __m); }
d466a7e2 643
50ce8d3d
BK
644 inline void*
645 atomic_fetch_add(volatile atomic_address* __a, ptrdiff_t __d)
646 { return __a->fetch_add(__d); }
d466a7e2 647
50ce8d3d
BK
648 inline void*
649 atomic_fetch_sub_explicit(volatile atomic_address* __a, ptrdiff_t __d,
650 memory_order __m)
651 { return __a->fetch_sub(__d, __m); }
d466a7e2 652
50ce8d3d
BK
653 inline void*
654 atomic_fetch_sub(volatile atomic_address* __a, ptrdiff_t __d)
655 { return __a->fetch_sub(__d); }
d466a7e2 656
d466a7e2 657
50ce8d3d
BK
658 // Convenience function definitions, atomic_bool.
659 inline bool
660 atomic_is_lock_free(const volatile atomic_bool* __a)
661 { return __a->is_lock_free(); }
d466a7e2 662
50ce8d3d
BK
663 inline void
664 atomic_store(volatile atomic_bool* __a, bool __i)
665 { __a->store(__i); }
d466a7e2 666
50ce8d3d
BK
667 inline void
668 atomic_store_explicit(volatile atomic_bool* __a, bool __i, memory_order __m)
669 { __a->store(__i, __m); }
d466a7e2
BK
670
671 inline bool
50ce8d3d
BK
672 atomic_load(const volatile atomic_bool* __a)
673 { return __a->load(); }
d466a7e2 674
50ce8d3d
BK
675 inline bool
676 atomic_load_explicit(const volatile atomic_bool* __a, memory_order __m)
677 { return __a->load(__m); }
d466a7e2 678
50ce8d3d
BK
679 inline bool
680 atomic_exchange(volatile atomic_bool* __a, bool __i)
681 { return __a->exchange(__i); }
d466a7e2
BK
682
683 inline bool
50ce8d3d
BK
684 atomic_exchange_explicit(volatile atomic_bool* __a, bool __i,
685 memory_order __m)
686 { return __a->exchange(__i, __m); }
d466a7e2
BK
687
688 inline bool
50ce8d3d
BK
689 atomic_compare_exchange_weak(volatile atomic_bool* __a, bool* __i1, bool __i2)
690 {
691 return __a->compare_exchange_weak(*__i1, __i2, memory_order_seq_cst,
692 memory_order_seq_cst);
d466a7e2
BK
693 }
694
50ce8d3d
BK
695 inline bool
696 atomic_compare_exchange_strong(volatile atomic_bool* __a,
697 bool* __i1, bool __i2)
698 {
699 return __a->compare_exchange_strong(*__i1, __i2, memory_order_seq_cst,
700 memory_order_seq_cst);
701 }
d466a7e2 702
50ce8d3d
BK
703 inline bool
704 atomic_compare_exchange_weak_explicit(volatile atomic_bool* __a, bool* __i1,
705 bool __i2, memory_order __m1,
706 memory_order __m2)
707 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
d466a7e2 708
50ce8d3d
BK
709 inline bool
710 atomic_compare_exchange_strong_explicit(volatile atomic_bool* __a,
711 bool* __i1, bool __i2,
712 memory_order __m1, memory_order __m2)
713 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
d466a7e2 714
d466a7e2 715
d466a7e2 716
50ce8d3d
BK
717 // Free standing functions. Template argument should be constricted
718 // to intergral types as specified in the standard.
719 template<typename _ITp>
720 inline void
721 atomic_store_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
722 memory_order __m)
723 { __a->store(__i, __m); }
724
725 template<typename _ITp>
726 inline _ITp
727 atomic_load_explicit(const volatile __atomic_base<_ITp>* __a,
728 memory_order __m)
729 { return __a->load(__m); }
730
731 template<typename _ITp>
732 inline _ITp
733 atomic_exchange_explicit(volatile __atomic_base<_ITp>* __a,
734 _ITp __i, memory_order __m)
735 { return __a->exchange(__i, __m); }
736
737 template<typename _ITp>
d466a7e2 738 inline bool
50ce8d3d
BK
739 atomic_compare_exchange_weak_explicit(volatile __atomic_base<_ITp>* __a,
740 _ITp* __i1, _ITp __i2,
741 memory_order __m1, memory_order __m2)
742 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
d466a7e2 743
50ce8d3d 744 template<typename _ITp>
d466a7e2 745 inline bool
50ce8d3d
BK
746 atomic_compare_exchange_strong_explicit(volatile __atomic_base<_ITp>* __a,
747 _ITp* __i1, _ITp __i2,
748 memory_order __m1,
749 memory_order __m2)
750 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
751
752 template<typename _ITp>
753 inline _ITp
754 atomic_fetch_add_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
755 memory_order __m)
756 { return __a->fetch_add(__i, __m); }
757
758 template<typename _ITp>
759 inline _ITp
760 atomic_fetch_sub_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
761 memory_order __m)
762 { return __a->fetch_sub(__i, __m); }
763
764 template<typename _ITp>
765 inline _ITp
766 atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
767 memory_order __m)
768 { return __a->fetch_and(__i, __m); }
769
770 template<typename _ITp>
771 inline _ITp
772 atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
773 memory_order __m)
774 { return __a->fetch_or(__i, __m); }
775
776 template<typename _ITp>
777 inline _ITp
778 atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
779 memory_order __m)
780 { return __a->fetch_xor(__i, __m); }
781
782 template<typename _ITp>
783 inline bool
784 atomic_is_lock_free(const volatile __atomic_base<_ITp>* __a)
785 { return __a->is_lock_free(); }
d466a7e2 786
50ce8d3d
BK
787 template<typename _ITp>
788 inline void
789 atomic_store(volatile __atomic_base<_ITp>* __a, _ITp __i)
790 { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
d466a7e2 791
50ce8d3d
BK
792 template<typename _ITp>
793 inline _ITp
794 atomic_load(const volatile __atomic_base<_ITp>* __a)
795 { return atomic_load_explicit(__a, memory_order_seq_cst); }
d466a7e2 796
50ce8d3d
BK
797 template<typename _ITp>
798 inline _ITp
799 atomic_exchange(volatile __atomic_base<_ITp>* __a, _ITp __i)
800 { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
d466a7e2 801
50ce8d3d
BK
802 template<typename _ITp>
803 inline bool
804 atomic_compare_exchange_weak(volatile __atomic_base<_ITp>* __a,
805 _ITp* __i1, _ITp __i2)
d466a7e2 806 {
50ce8d3d
BK
807 return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
808 memory_order_seq_cst,
809 memory_order_seq_cst);
d466a7e2
BK
810 }
811
50ce8d3d
BK
812 template<typename _ITp>
813 inline bool
814 atomic_compare_exchange_strong(volatile __atomic_base<_ITp>* __a,
815 _ITp* __i1, _ITp __i2)
d466a7e2 816 {
50ce8d3d
BK
817 return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
818 memory_order_seq_cst,
819 memory_order_seq_cst);
d466a7e2
BK
820 }
821
50ce8d3d
BK
822 template<typename _ITp>
823 inline _ITp
824 atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i)
825 { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
826
827 template<typename _ITp>
828 inline _ITp
829 atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i)
830 { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
831
832 template<typename _ITp>
833 inline _ITp
834 atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i)
835 { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
836
837 template<typename _ITp>
838 inline _ITp
839 atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i)
840 { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
841
842 template<typename _ITp>
843 inline _ITp
844 atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i)
845 { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
d466a7e2 846
5b9daa7e
BK
847 // @} group atomics
848
d466a7e2
BK
849_GLIBCXX_END_NAMESPACE
850
851#endif
852
853