Line data Source code
1 : // -*- C++ -*- header.
2 :
3 : // Copyright (C) 2008-2016 Free Software Foundation, Inc.
4 : //
5 : // This file is part of the GNU ISO C++ Library. This library is free
6 : // software; you can redistribute it and/or modify it under the
7 : // terms of the GNU General Public License as published by the
8 : // Free Software Foundation; either version 3, or (at your option)
9 : // any later version.
10 :
11 : // This library is distributed in the hope that it will be useful,
12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : // GNU General Public License for more details.
15 :
16 : // Under Section 7 of GPL version 3, you are granted additional
17 : // permissions described in the GCC Runtime Library Exception, version
18 : // 3.1, as published by the Free Software Foundation.
19 :
20 : // You should have received a copy of the GNU General Public License and
21 : // a copy of the GCC Runtime Library Exception along with this program;
22 : // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 : // <http://www.gnu.org/licenses/>.
24 :
25 : /** @file include/atomic
26 : * This is a Standard C++ Library header.
27 : */
28 :
29 : // Based on "C++ Atomic Types and Operations" by Hans Boehm and Lawrence Crowl.
30 : // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html
31 :
32 : #ifndef _GLIBCXX_ATOMIC
33 : #define _GLIBCXX_ATOMIC 1
34 :
35 : #pragma GCC system_header
36 :
37 : #if __cplusplus < 201103L
38 : # include <bits/c++0x_warning.h>
39 : #else
40 :
41 : #include <bits/atomic_base.h>
42 :
43 : namespace std _GLIBCXX_VISIBILITY(default)
44 : {
45 : _GLIBCXX_BEGIN_NAMESPACE_VERSION
46 :
47 : /**
48 : * @addtogroup atomics
49 : * @{
50 : */
51 :
52 : template<typename _Tp>
53 : struct atomic;
54 :
55 : /// atomic<bool>
56 : // NB: No operators or fetch-operations for this type.
57 : template<>
58 : struct atomic<bool>
59 : {
60 : private:
61 : __atomic_base<bool> _M_base;
62 :
63 : public:
64 : atomic() noexcept = default;
65 : ~atomic() noexcept = default;
66 : atomic(const atomic&) = delete;
67 : atomic& operator=(const atomic&) = delete;
68 : atomic& operator=(const atomic&) volatile = delete;
69 :
70 : constexpr atomic(bool __i) noexcept : _M_base(__i) { }
71 :
72 : bool
73 : operator=(bool __i) noexcept
74 : { return _M_base.operator=(__i); }
75 :
76 : bool
77 : operator=(bool __i) volatile noexcept
78 : { return _M_base.operator=(__i); }
79 :
80 : operator bool() const noexcept
81 : { return _M_base.load(); }
82 :
83 : operator bool() const volatile noexcept
84 : { return _M_base.load(); }
85 :
86 : bool
87 : is_lock_free() const noexcept { return _M_base.is_lock_free(); }
88 :
89 : bool
90 : is_lock_free() const volatile noexcept { return _M_base.is_lock_free(); }
91 :
92 : void
93 : store(bool __i, memory_order __m = memory_order_seq_cst) noexcept
94 : { _M_base.store(__i, __m); }
95 :
96 : void
97 : store(bool __i, memory_order __m = memory_order_seq_cst) volatile noexcept
98 : { _M_base.store(__i, __m); }
99 :
100 : bool
101 23 : load(memory_order __m = memory_order_seq_cst) const noexcept
102 46 : { return _M_base.load(__m); }
103 :
104 : bool
105 : load(memory_order __m = memory_order_seq_cst) const volatile noexcept
106 : { return _M_base.load(__m); }
107 :
108 : bool
109 : exchange(bool __i, memory_order __m = memory_order_seq_cst) noexcept
110 : { return _M_base.exchange(__i, __m); }
111 :
112 : bool
113 : exchange(bool __i,
114 : memory_order __m = memory_order_seq_cst) volatile noexcept
115 : { return _M_base.exchange(__i, __m); }
116 :
117 : bool
118 : compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
119 : memory_order __m2) noexcept
120 : { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
121 :
122 : bool
123 : compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
124 : memory_order __m2) volatile noexcept
125 : { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
126 :
127 : bool
128 : compare_exchange_weak(bool& __i1, bool __i2,
129 : memory_order __m = memory_order_seq_cst) noexcept
130 : { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
131 :
132 : bool
133 : compare_exchange_weak(bool& __i1, bool __i2,
134 : memory_order __m = memory_order_seq_cst) volatile noexcept
135 : { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
136 :
137 : bool
138 : compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
139 : memory_order __m2) noexcept
140 : { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
141 :
142 : bool
143 : compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
144 : memory_order __m2) volatile noexcept
145 : { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
146 :
147 : bool
148 : compare_exchange_strong(bool& __i1, bool __i2,
149 : memory_order __m = memory_order_seq_cst) noexcept
150 : { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
151 :
152 : bool
153 : compare_exchange_strong(bool& __i1, bool __i2,
154 : memory_order __m = memory_order_seq_cst) volatile noexcept
155 : { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
156 : };
157 :
158 :
159 : /**
160 : * @brief Generic atomic type, primary class template.
161 : *
162 : * @tparam _Tp Type to be made atomic, must be trivally copyable.
163 : */
164 : template<typename _Tp>
165 : struct atomic
166 : {
167 : private:
168 : // Align 1/2/4/8/16-byte types to at least their size.
169 : static constexpr int _S_min_alignment
170 : = (sizeof(_Tp) & (sizeof(_Tp) - 1)) || sizeof(_Tp) > 16
171 : ? 0 : sizeof(_Tp);
172 :
173 : static constexpr int _S_alignment
174 : = _S_min_alignment > alignof(_Tp) ? _S_min_alignment : alignof(_Tp);
175 :
176 : alignas(_S_alignment) _Tp _M_i;
177 :
178 : static_assert(__is_trivially_copyable(_Tp),
179 : "std::atomic requires a trivially copyable type");
180 :
181 : static_assert(sizeof(_Tp) > 0,
182 : "Incomplete or zero-sized types are not supported");
183 :
184 : public:
185 : atomic() noexcept = default;
186 : ~atomic() noexcept = default;
187 : atomic(const atomic&) = delete;
188 : atomic& operator=(const atomic&) = delete;
189 : atomic& operator=(const atomic&) volatile = delete;
190 :
191 : constexpr atomic(_Tp __i) noexcept : _M_i(__i) { }
192 :
193 : operator _Tp() const noexcept
194 : { return load(); }
195 :
196 : operator _Tp() const volatile noexcept
197 : { return load(); }
198 :
199 : _Tp
200 : operator=(_Tp __i) noexcept
201 : { store(__i); return __i; }
202 :
203 : _Tp
204 : operator=(_Tp __i) volatile noexcept
205 : { store(__i); return __i; }
206 :
207 : bool
208 : is_lock_free() const noexcept
209 : {
210 : // Produce a fake, minimally aligned pointer.
211 : return __atomic_is_lock_free(sizeof(_M_i),
212 : reinterpret_cast<void *>(-__alignof(_M_i)));
213 : }
214 :
215 : bool
216 : is_lock_free() const volatile noexcept
217 : {
218 : // Produce a fake, minimally aligned pointer.
219 : return __atomic_is_lock_free(sizeof(_M_i),
220 : reinterpret_cast<void *>(-__alignof(_M_i)));
221 : }
222 :
223 : void
224 : store(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept
225 : { __atomic_store(&_M_i, &__i, __m); }
226 :
227 : void
228 : store(_Tp __i, memory_order __m = memory_order_seq_cst) volatile noexcept
229 : { __atomic_store(&_M_i, &__i, __m); }
230 :
231 : _Tp
232 : load(memory_order __m = memory_order_seq_cst) const noexcept
233 : {
234 : alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
235 : _Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
236 : __atomic_load(&_M_i, __ptr, __m);
237 : return *__ptr;
238 : }
239 :
240 : _Tp
241 : load(memory_order __m = memory_order_seq_cst) const volatile noexcept
242 : {
243 : alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
244 : _Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
245 : __atomic_load(&_M_i, __ptr, __m);
246 : return *__ptr;
247 : }
248 :
249 : _Tp
250 : exchange(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept
251 : {
252 : alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
253 : _Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
254 : __atomic_exchange(&_M_i, &__i, __ptr, __m);
255 : return *__ptr;
256 : }
257 :
258 : _Tp
259 : exchange(_Tp __i,
260 : memory_order __m = memory_order_seq_cst) volatile noexcept
261 : {
262 : alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
263 : _Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
264 : __atomic_exchange(&_M_i, &__i, __ptr, __m);
265 : return *__ptr;
266 : }
267 :
268 : bool
269 : compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s,
270 : memory_order __f) noexcept
271 : {
272 : return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f);
273 : }
274 :
275 : bool
276 : compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s,
277 : memory_order __f) volatile noexcept
278 : {
279 : return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f);
280 : }
281 :
282 : bool
283 : compare_exchange_weak(_Tp& __e, _Tp __i,
284 : memory_order __m = memory_order_seq_cst) noexcept
285 : { return compare_exchange_weak(__e, __i, __m,
286 : __cmpexch_failure_order(__m)); }
287 :
288 : bool
289 : compare_exchange_weak(_Tp& __e, _Tp __i,
290 : memory_order __m = memory_order_seq_cst) volatile noexcept
291 : { return compare_exchange_weak(__e, __i, __m,
292 : __cmpexch_failure_order(__m)); }
293 :
294 : bool
295 : compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s,
296 : memory_order __f) noexcept
297 : {
298 : return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f);
299 : }
300 :
301 : bool
302 : compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s,
303 : memory_order __f) volatile noexcept
304 : {
305 : return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f);
306 : }
307 :
308 : bool
309 : compare_exchange_strong(_Tp& __e, _Tp __i,
310 : memory_order __m = memory_order_seq_cst) noexcept
311 : { return compare_exchange_strong(__e, __i, __m,
312 : __cmpexch_failure_order(__m)); }
313 :
314 : bool
315 : compare_exchange_strong(_Tp& __e, _Tp __i,
316 : memory_order __m = memory_order_seq_cst) volatile noexcept
317 : { return compare_exchange_strong(__e, __i, __m,
318 : __cmpexch_failure_order(__m)); }
319 : };
320 :
321 :
322 : /// Partial specialization for pointer types.
323 : template<typename _Tp>
324 : struct atomic<_Tp*>
325 : {
326 : typedef _Tp* __pointer_type;
327 : typedef __atomic_base<_Tp*> __base_type;
328 : __base_type _M_b;
329 :
330 : atomic() noexcept = default;
331 : ~atomic() noexcept = default;
332 : atomic(const atomic&) = delete;
333 : atomic& operator=(const atomic&) = delete;
334 : atomic& operator=(const atomic&) volatile = delete;
335 :
336 : constexpr atomic(__pointer_type __p) noexcept : _M_b(__p) { }
337 :
338 : operator __pointer_type() const noexcept
339 : { return __pointer_type(_M_b); }
340 :
341 : operator __pointer_type() const volatile noexcept
342 : { return __pointer_type(_M_b); }
343 :
344 : __pointer_type
345 : operator=(__pointer_type __p) noexcept
346 : { return _M_b.operator=(__p); }
347 :
348 : __pointer_type
349 : operator=(__pointer_type __p) volatile noexcept
350 : { return _M_b.operator=(__p); }
351 :
352 : __pointer_type
353 : operator++(int) noexcept
354 : { return _M_b++; }
355 :
356 : __pointer_type
357 : operator++(int) volatile noexcept
358 : { return _M_b++; }
359 :
360 : __pointer_type
361 : operator--(int) noexcept
362 : { return _M_b--; }
363 :
364 : __pointer_type
365 : operator--(int) volatile noexcept
366 : { return _M_b--; }
367 :
368 : __pointer_type
369 : operator++() noexcept
370 : { return ++_M_b; }
371 :
372 : __pointer_type
373 : operator++() volatile noexcept
374 : { return ++_M_b; }
375 :
376 : __pointer_type
377 : operator--() noexcept
378 : { return --_M_b; }
379 :
380 : __pointer_type
381 : operator--() volatile noexcept
382 : { return --_M_b; }
383 :
384 : __pointer_type
385 : operator+=(ptrdiff_t __d) noexcept
386 : { return _M_b.operator+=(__d); }
387 :
388 : __pointer_type
389 : operator+=(ptrdiff_t __d) volatile noexcept
390 : { return _M_b.operator+=(__d); }
391 :
392 : __pointer_type
393 : operator-=(ptrdiff_t __d) noexcept
394 : { return _M_b.operator-=(__d); }
395 :
396 : __pointer_type
397 : operator-=(ptrdiff_t __d) volatile noexcept
398 : { return _M_b.operator-=(__d); }
399 :
400 : bool
401 : is_lock_free() const noexcept
402 : { return _M_b.is_lock_free(); }
403 :
404 : bool
405 : is_lock_free() const volatile noexcept
406 : { return _M_b.is_lock_free(); }
407 :
408 : void
409 : store(__pointer_type __p,
410 : memory_order __m = memory_order_seq_cst) noexcept
411 : { return _M_b.store(__p, __m); }
412 :
413 : void
414 : store(__pointer_type __p,
415 : memory_order __m = memory_order_seq_cst) volatile noexcept
416 : { return _M_b.store(__p, __m); }
417 :
418 : __pointer_type
419 : load(memory_order __m = memory_order_seq_cst) const noexcept
420 : { return _M_b.load(__m); }
421 :
422 : __pointer_type
423 : load(memory_order __m = memory_order_seq_cst) const volatile noexcept
424 : { return _M_b.load(__m); }
425 :
426 : __pointer_type
427 : exchange(__pointer_type __p,
428 : memory_order __m = memory_order_seq_cst) noexcept
429 : { return _M_b.exchange(__p, __m); }
430 :
431 : __pointer_type
432 : exchange(__pointer_type __p,
433 : memory_order __m = memory_order_seq_cst) volatile noexcept
434 : { return _M_b.exchange(__p, __m); }
435 :
436 : bool
437 : compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
438 : memory_order __m1, memory_order __m2) noexcept
439 : { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
440 :
441 : bool
442 : compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
443 : memory_order __m1,
444 : memory_order __m2) volatile noexcept
445 : { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
446 :
447 : bool
448 : compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
449 : memory_order __m = memory_order_seq_cst) noexcept
450 : {
451 : return compare_exchange_weak(__p1, __p2, __m,
452 : __cmpexch_failure_order(__m));
453 : }
454 :
455 : bool
456 : compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
457 : memory_order __m = memory_order_seq_cst) volatile noexcept
458 : {
459 : return compare_exchange_weak(__p1, __p2, __m,
460 : __cmpexch_failure_order(__m));
461 : }
462 :
463 : bool
464 : compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
465 : memory_order __m1, memory_order __m2) noexcept
466 : { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
467 :
468 : bool
469 : compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
470 : memory_order __m1,
471 : memory_order __m2) volatile noexcept
472 : { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
473 :
474 : bool
475 : compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
476 : memory_order __m = memory_order_seq_cst) noexcept
477 : {
478 : return _M_b.compare_exchange_strong(__p1, __p2, __m,
479 : __cmpexch_failure_order(__m));
480 : }
481 :
482 : bool
483 : compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
484 : memory_order __m = memory_order_seq_cst) volatile noexcept
485 : {
486 : return _M_b.compare_exchange_strong(__p1, __p2, __m,
487 : __cmpexch_failure_order(__m));
488 : }
489 :
490 : __pointer_type
491 : fetch_add(ptrdiff_t __d,
492 : memory_order __m = memory_order_seq_cst) noexcept
493 : { return _M_b.fetch_add(__d, __m); }
494 :
495 : __pointer_type
496 : fetch_add(ptrdiff_t __d,
497 : memory_order __m = memory_order_seq_cst) volatile noexcept
498 : { return _M_b.fetch_add(__d, __m); }
499 :
500 : __pointer_type
501 : fetch_sub(ptrdiff_t __d,
502 : memory_order __m = memory_order_seq_cst) noexcept
503 : { return _M_b.fetch_sub(__d, __m); }
504 :
505 : __pointer_type
506 : fetch_sub(ptrdiff_t __d,
507 : memory_order __m = memory_order_seq_cst) volatile noexcept
508 : { return _M_b.fetch_sub(__d, __m); }
509 : };
510 :
511 :
512 : /// Explicit specialization for char.
513 : template<>
514 : struct atomic<char> : __atomic_base<char>
515 : {
516 : typedef char __integral_type;
517 : typedef __atomic_base<char> __base_type;
518 :
519 : atomic() noexcept = default;
520 : ~atomic() noexcept = default;
521 : atomic(const atomic&) = delete;
522 : atomic& operator=(const atomic&) = delete;
523 : atomic& operator=(const atomic&) volatile = delete;
524 :
525 : constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
526 :
527 : using __base_type::operator __integral_type;
528 : using __base_type::operator=;
529 : };
530 :
531 : /// Explicit specialization for signed char.
532 : template<>
533 : struct atomic<signed char> : __atomic_base<signed char>
534 : {
535 : typedef signed char __integral_type;
536 : typedef __atomic_base<signed char> __base_type;
537 :
538 : atomic() noexcept= default;
539 : ~atomic() noexcept = default;
540 : atomic(const atomic&) = delete;
541 : atomic& operator=(const atomic&) = delete;
542 : atomic& operator=(const atomic&) volatile = delete;
543 :
544 : constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
545 :
546 : using __base_type::operator __integral_type;
547 : using __base_type::operator=;
548 : };
549 :
550 : /// Explicit specialization for unsigned char.
551 : template<>
552 : struct atomic<unsigned char> : __atomic_base<unsigned char>
553 : {
554 : typedef unsigned char __integral_type;
555 : typedef __atomic_base<unsigned char> __base_type;
556 :
557 : atomic() noexcept= default;
558 : ~atomic() noexcept = default;
559 : atomic(const atomic&) = delete;
560 : atomic& operator=(const atomic&) = delete;
561 : atomic& operator=(const atomic&) volatile = delete;
562 :
563 : constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
564 :
565 : using __base_type::operator __integral_type;
566 : using __base_type::operator=;
567 : };
568 :
569 : /// Explicit specialization for short.
570 : template<>
571 : struct atomic<short> : __atomic_base<short>
572 : {
573 : typedef short __integral_type;
574 : typedef __atomic_base<short> __base_type;
575 :
576 : atomic() noexcept = default;
577 : ~atomic() noexcept = default;
578 : atomic(const atomic&) = delete;
579 : atomic& operator=(const atomic&) = delete;
580 : atomic& operator=(const atomic&) volatile = delete;
581 :
582 : constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
583 :
584 : using __base_type::operator __integral_type;
585 : using __base_type::operator=;
586 : };
587 :
588 : /// Explicit specialization for unsigned short.
589 : template<>
590 : struct atomic<unsigned short> : __atomic_base<unsigned short>
591 : {
592 : typedef unsigned short __integral_type;
593 : typedef __atomic_base<unsigned short> __base_type;
594 :
595 : atomic() noexcept = default;
596 : ~atomic() noexcept = default;
597 : atomic(const atomic&) = delete;
598 : atomic& operator=(const atomic&) = delete;
599 : atomic& operator=(const atomic&) volatile = delete;
600 :
601 : constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
602 :
603 : using __base_type::operator __integral_type;
604 : using __base_type::operator=;
605 : };
606 :
607 : /// Explicit specialization for int.
608 : template<>
609 : struct atomic<int> : __atomic_base<int>
610 : {
611 : typedef int __integral_type;
612 : typedef __atomic_base<int> __base_type;
613 :
614 : atomic() noexcept = default;
615 : ~atomic() noexcept = default;
616 : atomic(const atomic&) = delete;
617 : atomic& operator=(const atomic&) = delete;
618 : atomic& operator=(const atomic&) volatile = delete;
619 :
620 100 : constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
621 :
622 : using __base_type::operator __integral_type;
623 : using __base_type::operator=;
624 : };
625 :
626 : /// Explicit specialization for unsigned int.
627 : template<>
628 : struct atomic<unsigned int> : __atomic_base<unsigned int>
629 : {
630 : typedef unsigned int __integral_type;
631 : typedef __atomic_base<unsigned int> __base_type;
632 :
633 : atomic() noexcept = default;
634 : ~atomic() noexcept = default;
635 : atomic(const atomic&) = delete;
636 : atomic& operator=(const atomic&) = delete;
637 : atomic& operator=(const atomic&) volatile = delete;
638 :
639 : constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
640 :
641 : using __base_type::operator __integral_type;
642 : using __base_type::operator=;
643 : };
644 :
645 : /// Explicit specialization for long.
646 : template<>
647 : struct atomic<long> : __atomic_base<long>
648 : {
649 : typedef long __integral_type;
650 : typedef __atomic_base<long> __base_type;
651 :
652 : atomic() noexcept = default;
653 : ~atomic() noexcept = default;
654 : atomic(const atomic&) = delete;
655 : atomic& operator=(const atomic&) = delete;
656 : atomic& operator=(const atomic&) volatile = delete;
657 :
658 : constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
659 :
660 : using __base_type::operator __integral_type;
661 : using __base_type::operator=;
662 : };
663 :
664 : /// Explicit specialization for unsigned long.
665 : template<>
666 : struct atomic<unsigned long> : __atomic_base<unsigned long>
667 : {
668 : typedef unsigned long __integral_type;
669 : typedef __atomic_base<unsigned long> __base_type;
670 :
671 : atomic() noexcept = default;
672 : ~atomic() noexcept = default;
673 : atomic(const atomic&) = delete;
674 : atomic& operator=(const atomic&) = delete;
675 : atomic& operator=(const atomic&) volatile = delete;
676 :
677 : constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
678 :
679 : using __base_type::operator __integral_type;
680 : using __base_type::operator=;
681 : };
682 :
683 : /// Explicit specialization for long long.
684 : template<>
685 : struct atomic<long long> : __atomic_base<long long>
686 : {
687 : typedef long long __integral_type;
688 : typedef __atomic_base<long long> __base_type;
689 :
690 : atomic() noexcept = default;
691 : ~atomic() noexcept = default;
692 : atomic(const atomic&) = delete;
693 : atomic& operator=(const atomic&) = delete;
694 : atomic& operator=(const atomic&) volatile = delete;
695 :
696 : constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
697 :
698 : using __base_type::operator __integral_type;
699 : using __base_type::operator=;
700 : };
701 :
702 : /// Explicit specialization for unsigned long long.
703 : template<>
704 : struct atomic<unsigned long long> : __atomic_base<unsigned long long>
705 : {
706 : typedef unsigned long long __integral_type;
707 : typedef __atomic_base<unsigned long long> __base_type;
708 :
709 : atomic() noexcept = default;
710 : ~atomic() noexcept = default;
711 : atomic(const atomic&) = delete;
712 : atomic& operator=(const atomic&) = delete;
713 : atomic& operator=(const atomic&) volatile = delete;
714 :
715 : constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
716 :
717 : using __base_type::operator __integral_type;
718 : using __base_type::operator=;
719 : };
720 :
721 : /// Explicit specialization for wchar_t.
722 : template<>
723 : struct atomic<wchar_t> : __atomic_base<wchar_t>
724 : {
725 : typedef wchar_t __integral_type;
726 : typedef __atomic_base<wchar_t> __base_type;
727 :
728 : atomic() noexcept = default;
729 : ~atomic() noexcept = default;
730 : atomic(const atomic&) = delete;
731 : atomic& operator=(const atomic&) = delete;
732 : atomic& operator=(const atomic&) volatile = delete;
733 :
734 : constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
735 :
736 : using __base_type::operator __integral_type;
737 : using __base_type::operator=;
738 : };
739 :
740 : /// Explicit specialization for char16_t.
741 : template<>
742 : struct atomic<char16_t> : __atomic_base<char16_t>
743 : {
744 : typedef char16_t __integral_type;
745 : typedef __atomic_base<char16_t> __base_type;
746 :
747 : atomic() noexcept = default;
748 : ~atomic() noexcept = default;
749 : atomic(const atomic&) = delete;
750 : atomic& operator=(const atomic&) = delete;
751 : atomic& operator=(const atomic&) volatile = delete;
752 :
753 : constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
754 :
755 : using __base_type::operator __integral_type;
756 : using __base_type::operator=;
757 : };
758 :
759 : /// Explicit specialization for char32_t.
760 : template<>
761 : struct atomic<char32_t> : __atomic_base<char32_t>
762 : {
763 : typedef char32_t __integral_type;
764 : typedef __atomic_base<char32_t> __base_type;
765 :
766 : atomic() noexcept = default;
767 : ~atomic() noexcept = default;
768 : atomic(const atomic&) = delete;
769 : atomic& operator=(const atomic&) = delete;
770 : atomic& operator=(const atomic&) volatile = delete;
771 :
772 : constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
773 :
774 : using __base_type::operator __integral_type;
775 : using __base_type::operator=;
776 : };
777 :
778 :
779 : /// atomic_bool
780 : typedef atomic<bool> atomic_bool;
781 :
782 : /// atomic_char
783 : typedef atomic<char> atomic_char;
784 :
785 : /// atomic_schar
786 : typedef atomic<signed char> atomic_schar;
787 :
788 : /// atomic_uchar
789 : typedef atomic<unsigned char> atomic_uchar;
790 :
791 : /// atomic_short
792 : typedef atomic<short> atomic_short;
793 :
794 : /// atomic_ushort
795 : typedef atomic<unsigned short> atomic_ushort;
796 :
797 : /// atomic_int
798 : typedef atomic<int> atomic_int;
799 :
800 : /// atomic_uint
801 : typedef atomic<unsigned int> atomic_uint;
802 :
803 : /// atomic_long
804 : typedef atomic<long> atomic_long;
805 :
806 : /// atomic_ulong
807 : typedef atomic<unsigned long> atomic_ulong;
808 :
809 : /// atomic_llong
810 : typedef atomic<long long> atomic_llong;
811 :
812 : /// atomic_ullong
813 : typedef atomic<unsigned long long> atomic_ullong;
814 :
815 : /// atomic_wchar_t
816 : typedef atomic<wchar_t> atomic_wchar_t;
817 :
818 : /// atomic_char16_t
819 : typedef atomic<char16_t> atomic_char16_t;
820 :
821 : /// atomic_char32_t
822 : typedef atomic<char32_t> atomic_char32_t;
823 :
824 :
825 : /// atomic_int_least8_t
826 : typedef atomic<int_least8_t> atomic_int_least8_t;
827 :
828 : /// atomic_uint_least8_t
829 : typedef atomic<uint_least8_t> atomic_uint_least8_t;
830 :
831 : /// atomic_int_least16_t
832 : typedef atomic<int_least16_t> atomic_int_least16_t;
833 :
834 : /// atomic_uint_least16_t
835 : typedef atomic<uint_least16_t> atomic_uint_least16_t;
836 :
837 : /// atomic_int_least32_t
838 : typedef atomic<int_least32_t> atomic_int_least32_t;
839 :
840 : /// atomic_uint_least32_t
841 : typedef atomic<uint_least32_t> atomic_uint_least32_t;
842 :
843 : /// atomic_int_least64_t
844 : typedef atomic<int_least64_t> atomic_int_least64_t;
845 :
846 : /// atomic_uint_least64_t
847 : typedef atomic<uint_least64_t> atomic_uint_least64_t;
848 :
849 :
850 : /// atomic_int_fast8_t
851 : typedef atomic<int_fast8_t> atomic_int_fast8_t;
852 :
853 : /// atomic_uint_fast8_t
854 : typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
855 :
856 : /// atomic_int_fast16_t
857 : typedef atomic<int_fast16_t> atomic_int_fast16_t;
858 :
859 : /// atomic_uint_fast16_t
860 : typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
861 :
862 : /// atomic_int_fast32_t
863 : typedef atomic<int_fast32_t> atomic_int_fast32_t;
864 :
865 : /// atomic_uint_fast32_t
866 : typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
867 :
868 : /// atomic_int_fast64_t
869 : typedef atomic<int_fast64_t> atomic_int_fast64_t;
870 :
871 : /// atomic_uint_fast64_t
872 : typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
873 :
874 :
875 : /// atomic_intptr_t
876 : typedef atomic<intptr_t> atomic_intptr_t;
877 :
878 : /// atomic_uintptr_t
879 : typedef atomic<uintptr_t> atomic_uintptr_t;
880 :
881 : /// atomic_size_t
882 : typedef atomic<size_t> atomic_size_t;
883 :
884 : /// atomic_intmax_t
885 : typedef atomic<intmax_t> atomic_intmax_t;
886 :
887 : /// atomic_uintmax_t
888 : typedef atomic<uintmax_t> atomic_uintmax_t;
889 :
890 : /// atomic_ptrdiff_t
891 : typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
892 :
893 :
894 : // Function definitions, atomic_flag operations.
895 : inline bool
896 : atomic_flag_test_and_set_explicit(atomic_flag* __a,
897 : memory_order __m) noexcept
898 : { return __a->test_and_set(__m); }
899 :
900 : inline bool
901 : atomic_flag_test_and_set_explicit(volatile atomic_flag* __a,
902 : memory_order __m) noexcept
903 : { return __a->test_and_set(__m); }
904 :
905 : inline void
906 : atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept
907 : { __a->clear(__m); }
908 :
909 : inline void
910 : atomic_flag_clear_explicit(volatile atomic_flag* __a,
911 : memory_order __m) noexcept
912 : { __a->clear(__m); }
913 :
914 : inline bool
915 : atomic_flag_test_and_set(atomic_flag* __a) noexcept
916 : { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
917 :
918 : inline bool
919 : atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept
920 : { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
921 :
922 : inline void
923 : atomic_flag_clear(atomic_flag* __a) noexcept
924 : { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
925 :
926 : inline void
927 : atomic_flag_clear(volatile atomic_flag* __a) noexcept
928 : { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
929 :
930 :
931 : // Function templates generally applicable to atomic types.
932 : template<typename _ITp>
933 : inline bool
934 : atomic_is_lock_free(const atomic<_ITp>* __a) noexcept
935 : { return __a->is_lock_free(); }
936 :
937 : template<typename _ITp>
938 : inline bool
939 : atomic_is_lock_free(const volatile atomic<_ITp>* __a) noexcept
940 : { return __a->is_lock_free(); }
941 :
942 : template<typename _ITp>
943 : inline void
944 : atomic_init(atomic<_ITp>* __a, _ITp __i) noexcept
945 : { __a->store(__i, memory_order_relaxed); }
946 :
947 : template<typename _ITp>
948 : inline void
949 : atomic_init(volatile atomic<_ITp>* __a, _ITp __i) noexcept
950 : { __a->store(__i, memory_order_relaxed); }
951 :
952 : template<typename _ITp>
953 : inline void
954 : atomic_store_explicit(atomic<_ITp>* __a, _ITp __i,
955 : memory_order __m) noexcept
956 : { __a->store(__i, __m); }
957 :
958 : template<typename _ITp>
959 : inline void
960 : atomic_store_explicit(volatile atomic<_ITp>* __a, _ITp __i,
961 : memory_order __m) noexcept
962 : { __a->store(__i, __m); }
963 :
964 : template<typename _ITp>
965 : inline _ITp
966 : atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept
967 : { return __a->load(__m); }
968 :
969 : template<typename _ITp>
970 : inline _ITp
971 : atomic_load_explicit(const volatile atomic<_ITp>* __a,
972 : memory_order __m) noexcept
973 : { return __a->load(__m); }
974 :
975 : template<typename _ITp>
976 : inline _ITp
977 : atomic_exchange_explicit(atomic<_ITp>* __a, _ITp __i,
978 : memory_order __m) noexcept
979 : { return __a->exchange(__i, __m); }
980 :
981 : template<typename _ITp>
982 : inline _ITp
983 : atomic_exchange_explicit(volatile atomic<_ITp>* __a, _ITp __i,
984 : memory_order __m) noexcept
985 : { return __a->exchange(__i, __m); }
986 :
987 : template<typename _ITp>
988 : inline bool
989 : atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a,
990 : _ITp* __i1, _ITp __i2,
991 : memory_order __m1,
992 : memory_order __m2) noexcept
993 : { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
994 :
995 : template<typename _ITp>
996 : inline bool
997 : atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a,
998 : _ITp* __i1, _ITp __i2,
999 : memory_order __m1,
1000 : memory_order __m2) noexcept
1001 : { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
1002 :
1003 : template<typename _ITp>
1004 : inline bool
1005 : atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a,
1006 : _ITp* __i1, _ITp __i2,
1007 : memory_order __m1,
1008 : memory_order __m2) noexcept
1009 : { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
1010 :
1011 : template<typename _ITp>
1012 : inline bool
1013 : atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a,
1014 : _ITp* __i1, _ITp __i2,
1015 : memory_order __m1,
1016 : memory_order __m2) noexcept
1017 : { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
1018 :
1019 :
1020 : template<typename _ITp>
1021 : inline void
1022 : atomic_store(atomic<_ITp>* __a, _ITp __i) noexcept
1023 : { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
1024 :
1025 : template<typename _ITp>
1026 : inline void
1027 : atomic_store(volatile atomic<_ITp>* __a, _ITp __i) noexcept
1028 : { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
1029 :
1030 : template<typename _ITp>
1031 : inline _ITp
1032 : atomic_load(const atomic<_ITp>* __a) noexcept
1033 : { return atomic_load_explicit(__a, memory_order_seq_cst); }
1034 :
1035 : template<typename _ITp>
1036 : inline _ITp
1037 : atomic_load(const volatile atomic<_ITp>* __a) noexcept
1038 : { return atomic_load_explicit(__a, memory_order_seq_cst); }
1039 :
1040 : template<typename _ITp>
1041 : inline _ITp
1042 : atomic_exchange(atomic<_ITp>* __a, _ITp __i) noexcept
1043 : { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
1044 :
1045 : template<typename _ITp>
1046 : inline _ITp
1047 : atomic_exchange(volatile atomic<_ITp>* __a, _ITp __i) noexcept
1048 : { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
1049 :
1050 : template<typename _ITp>
1051 : inline bool
1052 : atomic_compare_exchange_weak(atomic<_ITp>* __a,
1053 : _ITp* __i1, _ITp __i2) noexcept
1054 : {
1055 : return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
1056 : memory_order_seq_cst,
1057 : memory_order_seq_cst);
1058 : }
1059 :
1060 : template<typename _ITp>
1061 : inline bool
1062 : atomic_compare_exchange_weak(volatile atomic<_ITp>* __a,
1063 : _ITp* __i1, _ITp __i2) noexcept
1064 : {
1065 : return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
1066 : memory_order_seq_cst,
1067 : memory_order_seq_cst);
1068 : }
1069 :
1070 : template<typename _ITp>
1071 : inline bool
1072 : atomic_compare_exchange_strong(atomic<_ITp>* __a,
1073 : _ITp* __i1, _ITp __i2) noexcept
1074 : {
1075 : return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
1076 : memory_order_seq_cst,
1077 : memory_order_seq_cst);
1078 : }
1079 :
1080 : template<typename _ITp>
1081 : inline bool
1082 : atomic_compare_exchange_strong(volatile atomic<_ITp>* __a,
1083 : _ITp* __i1, _ITp __i2) noexcept
1084 : {
1085 : return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
1086 : memory_order_seq_cst,
1087 : memory_order_seq_cst);
1088 : }
1089 :
1090 : // Function templates for atomic_integral operations only, using
1091 : // __atomic_base. Template argument should be constricted to
1092 : // intergral types as specified in the standard, excluding address
1093 : // types.
1094 : template<typename _ITp>
1095 : inline _ITp
1096 : atomic_fetch_add_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1097 : memory_order __m) noexcept
1098 : { return __a->fetch_add(__i, __m); }
1099 :
1100 : template<typename _ITp>
1101 : inline _ITp
1102 : atomic_fetch_add_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1103 : memory_order __m) noexcept
1104 : { return __a->fetch_add(__i, __m); }
1105 :
1106 : template<typename _ITp>
1107 : inline _ITp
1108 : atomic_fetch_sub_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1109 : memory_order __m) noexcept
1110 : { return __a->fetch_sub(__i, __m); }
1111 :
1112 : template<typename _ITp>
1113 : inline _ITp
1114 : atomic_fetch_sub_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1115 : memory_order __m) noexcept
1116 : { return __a->fetch_sub(__i, __m); }
1117 :
1118 : template<typename _ITp>
1119 : inline _ITp
1120 : atomic_fetch_and_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1121 : memory_order __m) noexcept
1122 : { return __a->fetch_and(__i, __m); }
1123 :
1124 : template<typename _ITp>
1125 : inline _ITp
1126 : atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1127 : memory_order __m) noexcept
1128 : { return __a->fetch_and(__i, __m); }
1129 :
1130 : template<typename _ITp>
1131 : inline _ITp
1132 : atomic_fetch_or_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1133 : memory_order __m) noexcept
1134 : { return __a->fetch_or(__i, __m); }
1135 :
1136 : template<typename _ITp>
1137 : inline _ITp
1138 : atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1139 : memory_order __m) noexcept
1140 : { return __a->fetch_or(__i, __m); }
1141 :
1142 : template<typename _ITp>
1143 : inline _ITp
1144 : atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1145 : memory_order __m) noexcept
1146 : { return __a->fetch_xor(__i, __m); }
1147 :
1148 : template<typename _ITp>
1149 : inline _ITp
1150 : atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1151 : memory_order __m) noexcept
1152 : { return __a->fetch_xor(__i, __m); }
1153 :
1154 : template<typename _ITp>
1155 : inline _ITp
1156 : atomic_fetch_add(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1157 : { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
1158 :
1159 : template<typename _ITp>
1160 : inline _ITp
1161 : atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1162 : { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
1163 :
1164 : template<typename _ITp>
1165 : inline _ITp
1166 : atomic_fetch_sub(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1167 : { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
1168 :
1169 : template<typename _ITp>
1170 : inline _ITp
1171 : atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1172 : { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
1173 :
1174 : template<typename _ITp>
1175 : inline _ITp
1176 : atomic_fetch_and(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1177 : { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
1178 :
1179 : template<typename _ITp>
1180 : inline _ITp
1181 : atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1182 : { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
1183 :
1184 : template<typename _ITp>
1185 : inline _ITp
1186 : atomic_fetch_or(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1187 : { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
1188 :
1189 : template<typename _ITp>
1190 : inline _ITp
1191 : atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1192 : { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
1193 :
1194 : template<typename _ITp>
1195 : inline _ITp
1196 : atomic_fetch_xor(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1197 : { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
1198 :
1199 : template<typename _ITp>
1200 : inline _ITp
1201 : atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1202 : { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
1203 :
1204 :
1205 : // Partial specializations for pointers.
1206 : template<typename _ITp>
1207 : inline _ITp*
1208 : atomic_fetch_add_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
1209 : memory_order __m) noexcept
1210 : { return __a->fetch_add(__d, __m); }
1211 :
1212 : template<typename _ITp>
1213 : inline _ITp*
1214 : atomic_fetch_add_explicit(volatile atomic<_ITp*>* __a, ptrdiff_t __d,
1215 : memory_order __m) noexcept
1216 : { return __a->fetch_add(__d, __m); }
1217 :
1218 : template<typename _ITp>
1219 : inline _ITp*
1220 : atomic_fetch_add(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1221 : { return __a->fetch_add(__d); }
1222 :
1223 : template<typename _ITp>
1224 : inline _ITp*
1225 : atomic_fetch_add(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1226 : { return __a->fetch_add(__d); }
1227 :
1228 : template<typename _ITp>
1229 : inline _ITp*
1230 : atomic_fetch_sub_explicit(volatile atomic<_ITp*>* __a,
1231 : ptrdiff_t __d, memory_order __m) noexcept
1232 : { return __a->fetch_sub(__d, __m); }
1233 :
1234 : template<typename _ITp>
1235 : inline _ITp*
1236 : atomic_fetch_sub_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
1237 : memory_order __m) noexcept
1238 : { return __a->fetch_sub(__d, __m); }
1239 :
1240 : template<typename _ITp>
1241 : inline _ITp*
1242 : atomic_fetch_sub(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1243 : { return __a->fetch_sub(__d); }
1244 :
1245 : template<typename _ITp>
1246 : inline _ITp*
1247 : atomic_fetch_sub(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1248 : { return __a->fetch_sub(__d); }
1249 : // @} group atomics
1250 :
1251 : _GLIBCXX_END_NAMESPACE_VERSION
1252 : } // namespace
1253 :
1254 : #endif // C++11
1255 :
1256 : #endif // _GLIBCXX_ATOMIC
|