30 #ifndef _GLIBCXX_ATOMIC_BASE_H 31 #define _GLIBCXX_ATOMIC_BASE_H 1 33 #pragma GCC system_header 39 #ifndef _GLIBCXX_ALWAYS_INLINE 40 #define _GLIBCXX_ALWAYS_INLINE inline __attribute__((__always_inline__)) 43 namespace std _GLIBCXX_VISIBILITY(default)
45 _GLIBCXX_BEGIN_NAMESPACE_VERSION
65 enum __memory_order_modifier
67 __memory_order_mask = 0x0ffff,
68 __memory_order_modifier_mask = 0xffff0000,
69 __memory_order_hle_acquire = 0x10000,
70 __memory_order_hle_release = 0x20000
89 return __m == memory_order_acq_rel ? memory_order_acquire
90 : __m == memory_order_release ? memory_order_relaxed : __m;
96 return memory_order(__cmpexch_failure_order2(__m & __memory_order_mask)
97 | (__m & __memory_order_modifier_mask));
100 _GLIBCXX_ALWAYS_INLINE
void 102 { __atomic_thread_fence(__m); }
104 _GLIBCXX_ALWAYS_INLINE
void 106 { __atomic_signal_fence(__m); }
109 template<
typename _Tp>
119 template<
typename _IntTp>
123 #define ATOMIC_VAR_INIT(_VI) { _VI } 125 template<
typename _Tp>
128 template<
typename _Tp>
132 #if __GCC_ATOMIC_TEST_AND_SET_TRUEVAL == 1 133 typedef bool __atomic_flag_data_type;
135 typedef unsigned char __atomic_flag_data_type;
148 _GLIBCXX_BEGIN_EXTERN_C
152 __atomic_flag_data_type _M_i;
155 _GLIBCXX_END_EXTERN_C
157 #define ATOMIC_FLAG_INIT { 0 } 173 _GLIBCXX_ALWAYS_INLINE
bool 174 test_and_set(
memory_order __m = memory_order_seq_cst) noexcept
176 return __atomic_test_and_set (&_M_i, __m);
179 _GLIBCXX_ALWAYS_INLINE
bool 180 test_and_set(
memory_order __m = memory_order_seq_cst)
volatile noexcept
182 return __atomic_test_and_set (&_M_i, __m);
185 _GLIBCXX_ALWAYS_INLINE
void 189 __glibcxx_assert(__b != memory_order_consume);
190 __glibcxx_assert(__b != memory_order_acquire);
191 __glibcxx_assert(__b != memory_order_acq_rel);
193 __atomic_clear (&_M_i, __m);
196 _GLIBCXX_ALWAYS_INLINE
void 197 clear(
memory_order __m = memory_order_seq_cst)
volatile noexcept
200 __glibcxx_assert(__b != memory_order_consume);
201 __glibcxx_assert(__b != memory_order_acquire);
202 __glibcxx_assert(__b != memory_order_acq_rel);
204 __atomic_clear (&_M_i, __m);
208 static constexpr __atomic_flag_data_type
210 {
return __i ? __GCC_ATOMIC_TEST_AND_SET_TRUEVAL : 0; }
238 template<
typename _ITp>
241 using value_type = _ITp;
242 using difference_type = value_type;
245 typedef _ITp __int_type;
247 static constexpr
int _S_alignment =
248 sizeof(_ITp) >
alignof(_ITp) ?
sizeof(_ITp) :
alignof(_ITp);
250 alignas(_S_alignment) __int_type _M_i;
260 constexpr
__atomic_base(__int_type __i) noexcept : _M_i (__i) { }
262 operator __int_type() const noexcept
265 operator __int_type() const volatile noexcept
269 operator=(__int_type __i) noexcept
276 operator=(__int_type __i)
volatile noexcept
283 operator++(
int) noexcept
284 {
return fetch_add(1); }
287 operator++(
int)
volatile noexcept
288 {
return fetch_add(1); }
291 operator--(
int) noexcept
292 {
return fetch_sub(1); }
295 operator--(
int)
volatile noexcept
296 {
return fetch_sub(1); }
299 operator++() noexcept
300 {
return __atomic_add_fetch(&_M_i, 1, memory_order_seq_cst); }
303 operator++() volatile noexcept
304 {
return __atomic_add_fetch(&_M_i, 1, memory_order_seq_cst); }
307 operator--() noexcept
308 {
return __atomic_sub_fetch(&_M_i, 1, memory_order_seq_cst); }
311 operator--() volatile noexcept
312 {
return __atomic_sub_fetch(&_M_i, 1, memory_order_seq_cst); }
315 operator+=(__int_type __i) noexcept
316 {
return __atomic_add_fetch(&_M_i, __i, memory_order_seq_cst); }
319 operator+=(__int_type __i)
volatile noexcept
320 {
return __atomic_add_fetch(&_M_i, __i, memory_order_seq_cst); }
323 operator-=(__int_type __i) noexcept
324 {
return __atomic_sub_fetch(&_M_i, __i, memory_order_seq_cst); }
327 operator-=(__int_type __i)
volatile noexcept
328 {
return __atomic_sub_fetch(&_M_i, __i, memory_order_seq_cst); }
331 operator&=(__int_type __i) noexcept
332 {
return __atomic_and_fetch(&_M_i, __i, memory_order_seq_cst); }
335 operator&=(__int_type __i)
volatile noexcept
336 {
return __atomic_and_fetch(&_M_i, __i, memory_order_seq_cst); }
339 operator|=(__int_type __i) noexcept
340 {
return __atomic_or_fetch(&_M_i, __i, memory_order_seq_cst); }
343 operator|=(__int_type __i)
volatile noexcept
344 {
return __atomic_or_fetch(&_M_i, __i, memory_order_seq_cst); }
347 operator^=(__int_type __i) noexcept
348 {
return __atomic_xor_fetch(&_M_i, __i, memory_order_seq_cst); }
351 operator^=(__int_type __i)
volatile noexcept
352 {
return __atomic_xor_fetch(&_M_i, __i, memory_order_seq_cst); }
355 is_lock_free() const noexcept
358 return __atomic_is_lock_free(
sizeof(_M_i),
359 reinterpret_cast<void *>(-_S_alignment));
363 is_lock_free() const volatile noexcept
366 return __atomic_is_lock_free(
sizeof(_M_i),
367 reinterpret_cast<void *>(-_S_alignment));
370 _GLIBCXX_ALWAYS_INLINE
void 371 store(__int_type __i,
memory_order __m = memory_order_seq_cst) noexcept
374 __glibcxx_assert(__b != memory_order_acquire);
375 __glibcxx_assert(__b != memory_order_acq_rel);
376 __glibcxx_assert(__b != memory_order_consume);
378 __atomic_store_n(&_M_i, __i, __m);
381 _GLIBCXX_ALWAYS_INLINE
void 382 store(__int_type __i,
383 memory_order __m = memory_order_seq_cst)
volatile noexcept
386 __glibcxx_assert(__b != memory_order_acquire);
387 __glibcxx_assert(__b != memory_order_acq_rel);
388 __glibcxx_assert(__b != memory_order_consume);
390 __atomic_store_n(&_M_i, __i, __m);
393 _GLIBCXX_ALWAYS_INLINE __int_type
394 load(
memory_order __m = memory_order_seq_cst)
const noexcept
397 __glibcxx_assert(__b != memory_order_release);
398 __glibcxx_assert(__b != memory_order_acq_rel);
400 return __atomic_load_n(&_M_i, __m);
403 _GLIBCXX_ALWAYS_INLINE __int_type
404 load(
memory_order __m = memory_order_seq_cst)
const volatile noexcept
407 __glibcxx_assert(__b != memory_order_release);
408 __glibcxx_assert(__b != memory_order_acq_rel);
410 return __atomic_load_n(&_M_i, __m);
413 _GLIBCXX_ALWAYS_INLINE __int_type
417 return __atomic_exchange_n(&_M_i, __i, __m);
421 _GLIBCXX_ALWAYS_INLINE __int_type
423 memory_order __m = memory_order_seq_cst)
volatile noexcept
425 return __atomic_exchange_n(&_M_i, __i, __m);
428 _GLIBCXX_ALWAYS_INLINE
bool 429 compare_exchange_weak(__int_type& __i1, __int_type __i2,
434 __glibcxx_assert(__b2 != memory_order_release);
435 __glibcxx_assert(__b2 != memory_order_acq_rel);
436 __glibcxx_assert(__b2 <= __b1);
438 return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 1, __m1, __m2);
441 _GLIBCXX_ALWAYS_INLINE
bool 442 compare_exchange_weak(__int_type& __i1, __int_type __i2,
448 __glibcxx_assert(__b2 != memory_order_release);
449 __glibcxx_assert(__b2 != memory_order_acq_rel);
450 __glibcxx_assert(__b2 <= __b1);
452 return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 1, __m1, __m2);
455 _GLIBCXX_ALWAYS_INLINE
bool 456 compare_exchange_weak(__int_type& __i1, __int_type __i2,
459 return compare_exchange_weak(__i1, __i2, __m,
460 __cmpexch_failure_order(__m));
463 _GLIBCXX_ALWAYS_INLINE
bool 464 compare_exchange_weak(__int_type& __i1, __int_type __i2,
465 memory_order __m = memory_order_seq_cst)
volatile noexcept
467 return compare_exchange_weak(__i1, __i2, __m,
468 __cmpexch_failure_order(__m));
471 _GLIBCXX_ALWAYS_INLINE
bool 472 compare_exchange_strong(__int_type& __i1, __int_type __i2,
477 __glibcxx_assert(__b2 != memory_order_release);
478 __glibcxx_assert(__b2 != memory_order_acq_rel);
479 __glibcxx_assert(__b2 <= __b1);
481 return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 0, __m1, __m2);
484 _GLIBCXX_ALWAYS_INLINE
bool 485 compare_exchange_strong(__int_type& __i1, __int_type __i2,
492 __glibcxx_assert(__b2 != memory_order_release);
493 __glibcxx_assert(__b2 != memory_order_acq_rel);
494 __glibcxx_assert(__b2 <= __b1);
496 return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 0, __m1, __m2);
499 _GLIBCXX_ALWAYS_INLINE
bool 500 compare_exchange_strong(__int_type& __i1, __int_type __i2,
503 return compare_exchange_strong(__i1, __i2, __m,
504 __cmpexch_failure_order(__m));
507 _GLIBCXX_ALWAYS_INLINE
bool 508 compare_exchange_strong(__int_type& __i1, __int_type __i2,
509 memory_order __m = memory_order_seq_cst)
volatile noexcept
511 return compare_exchange_strong(__i1, __i2, __m,
512 __cmpexch_failure_order(__m));
515 _GLIBCXX_ALWAYS_INLINE __int_type
516 fetch_add(__int_type __i,
518 {
return __atomic_fetch_add(&_M_i, __i, __m); }
520 _GLIBCXX_ALWAYS_INLINE __int_type
521 fetch_add(__int_type __i,
522 memory_order __m = memory_order_seq_cst)
volatile noexcept
523 {
return __atomic_fetch_add(&_M_i, __i, __m); }
525 _GLIBCXX_ALWAYS_INLINE __int_type
526 fetch_sub(__int_type __i,
528 {
return __atomic_fetch_sub(&_M_i, __i, __m); }
530 _GLIBCXX_ALWAYS_INLINE __int_type
531 fetch_sub(__int_type __i,
532 memory_order __m = memory_order_seq_cst)
volatile noexcept
533 {
return __atomic_fetch_sub(&_M_i, __i, __m); }
535 _GLIBCXX_ALWAYS_INLINE __int_type
536 fetch_and(__int_type __i,
538 {
return __atomic_fetch_and(&_M_i, __i, __m); }
540 _GLIBCXX_ALWAYS_INLINE __int_type
541 fetch_and(__int_type __i,
542 memory_order __m = memory_order_seq_cst)
volatile noexcept
543 {
return __atomic_fetch_and(&_M_i, __i, __m); }
545 _GLIBCXX_ALWAYS_INLINE __int_type
546 fetch_or(__int_type __i,
548 {
return __atomic_fetch_or(&_M_i, __i, __m); }
550 _GLIBCXX_ALWAYS_INLINE __int_type
551 fetch_or(__int_type __i,
552 memory_order __m = memory_order_seq_cst)
volatile noexcept
553 {
return __atomic_fetch_or(&_M_i, __i, __m); }
555 _GLIBCXX_ALWAYS_INLINE __int_type
556 fetch_xor(__int_type __i,
558 {
return __atomic_fetch_xor(&_M_i, __i, __m); }
560 _GLIBCXX_ALWAYS_INLINE __int_type
561 fetch_xor(__int_type __i,
562 memory_order __m = memory_order_seq_cst)
volatile noexcept
563 {
return __atomic_fetch_xor(&_M_i, __i, __m); }
568 template<
typename _PTp>
572 typedef _PTp* __pointer_type;
578 _M_type_size(ptrdiff_t __d)
const {
return __d *
sizeof(_PTp); }
581 _M_type_size(ptrdiff_t __d)
const volatile {
return __d *
sizeof(_PTp); }
591 constexpr
__atomic_base(__pointer_type __p) noexcept : _M_p (__p) { }
593 operator __pointer_type()
const noexcept
596 operator __pointer_type()
const volatile noexcept
600 operator=(__pointer_type __p) noexcept
607 operator=(__pointer_type __p)
volatile noexcept
614 operator++(
int) noexcept
615 {
return fetch_add(1); }
618 operator++(
int)
volatile noexcept
619 {
return fetch_add(1); }
622 operator--(
int) noexcept
623 {
return fetch_sub(1); }
626 operator--(
int)
volatile noexcept
627 {
return fetch_sub(1); }
630 operator++() noexcept
631 {
return __atomic_add_fetch(&_M_p, _M_type_size(1),
632 memory_order_seq_cst); }
635 operator++()
volatile noexcept
636 {
return __atomic_add_fetch(&_M_p, _M_type_size(1),
637 memory_order_seq_cst); }
640 operator--() noexcept
641 {
return __atomic_sub_fetch(&_M_p, _M_type_size(1),
642 memory_order_seq_cst); }
645 operator--()
volatile noexcept
646 {
return __atomic_sub_fetch(&_M_p, _M_type_size(1),
647 memory_order_seq_cst); }
650 operator+=(ptrdiff_t __d) noexcept
651 {
return __atomic_add_fetch(&_M_p, _M_type_size(__d),
652 memory_order_seq_cst); }
655 operator+=(ptrdiff_t __d)
volatile noexcept
656 {
return __atomic_add_fetch(&_M_p, _M_type_size(__d),
657 memory_order_seq_cst); }
660 operator-=(ptrdiff_t __d) noexcept
661 {
return __atomic_sub_fetch(&_M_p, _M_type_size(__d),
662 memory_order_seq_cst); }
665 operator-=(ptrdiff_t __d)
volatile noexcept
666 {
return __atomic_sub_fetch(&_M_p, _M_type_size(__d),
667 memory_order_seq_cst); }
670 is_lock_free()
const noexcept
673 return __atomic_is_lock_free(
sizeof(_M_p),
674 reinterpret_cast<void *>(-__alignof(_M_p)));
678 is_lock_free()
const volatile noexcept
681 return __atomic_is_lock_free(
sizeof(_M_p),
682 reinterpret_cast<void *>(-__alignof(_M_p)));
685 _GLIBCXX_ALWAYS_INLINE
void 686 store(__pointer_type __p,
691 __glibcxx_assert(__b != memory_order_acquire);
692 __glibcxx_assert(__b != memory_order_acq_rel);
693 __glibcxx_assert(__b != memory_order_consume);
695 __atomic_store_n(&_M_p, __p, __m);
698 _GLIBCXX_ALWAYS_INLINE
void 699 store(__pointer_type __p,
700 memory_order __m = memory_order_seq_cst)
volatile noexcept
703 __glibcxx_assert(__b != memory_order_acquire);
704 __glibcxx_assert(__b != memory_order_acq_rel);
705 __glibcxx_assert(__b != memory_order_consume);
707 __atomic_store_n(&_M_p, __p, __m);
710 _GLIBCXX_ALWAYS_INLINE __pointer_type
711 load(
memory_order __m = memory_order_seq_cst)
const noexcept
714 __glibcxx_assert(__b != memory_order_release);
715 __glibcxx_assert(__b != memory_order_acq_rel);
717 return __atomic_load_n(&_M_p, __m);
720 _GLIBCXX_ALWAYS_INLINE __pointer_type
721 load(
memory_order __m = memory_order_seq_cst)
const volatile noexcept
724 __glibcxx_assert(__b != memory_order_release);
725 __glibcxx_assert(__b != memory_order_acq_rel);
727 return __atomic_load_n(&_M_p, __m);
730 _GLIBCXX_ALWAYS_INLINE __pointer_type
734 return __atomic_exchange_n(&_M_p, __p, __m);
738 _GLIBCXX_ALWAYS_INLINE __pointer_type
740 memory_order __m = memory_order_seq_cst)
volatile noexcept
742 return __atomic_exchange_n(&_M_p, __p, __m);
745 _GLIBCXX_ALWAYS_INLINE
bool 746 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
752 __glibcxx_assert(__b2 != memory_order_release);
753 __glibcxx_assert(__b2 != memory_order_acq_rel);
754 __glibcxx_assert(__b2 <= __b1);
756 return __atomic_compare_exchange_n(&_M_p, &__p1, __p2, 0, __m1, __m2);
759 _GLIBCXX_ALWAYS_INLINE
bool 760 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
767 __glibcxx_assert(__b2 != memory_order_release);
768 __glibcxx_assert(__b2 != memory_order_acq_rel);
769 __glibcxx_assert(__b2 <= __b1);
771 return __atomic_compare_exchange_n(&_M_p, &__p1, __p2, 0, __m1, __m2);
774 _GLIBCXX_ALWAYS_INLINE __pointer_type
775 fetch_add(ptrdiff_t __d,
777 {
return __atomic_fetch_add(&_M_p, _M_type_size(__d), __m); }
779 _GLIBCXX_ALWAYS_INLINE __pointer_type
780 fetch_add(ptrdiff_t __d,
781 memory_order __m = memory_order_seq_cst)
volatile noexcept
782 {
return __atomic_fetch_add(&_M_p, _M_type_size(__d), __m); }
784 _GLIBCXX_ALWAYS_INLINE __pointer_type
785 fetch_sub(ptrdiff_t __d,
787 {
return __atomic_fetch_sub(&_M_p, _M_type_size(__d), __m); }
789 _GLIBCXX_ALWAYS_INLINE __pointer_type
790 fetch_sub(ptrdiff_t __d,
791 memory_order __m = memory_order_seq_cst)
volatile noexcept
792 {
return __atomic_fetch_sub(&_M_p, _M_type_size(__d), __m); }
797 _GLIBCXX_END_NAMESPACE_VERSION
Base type for atomic_flag.
bitset< _Nb > operator&(const bitset< _Nb > &__x, const bitset< _Nb > &__y) noexcept
Global bitwise operations on bitsets.
Base class for atomic integrals.
ISO C++ entities toplevel namespace is std.
Generic atomic type, primary class template.
_Tp exchange(_Tp &__obj, _Up &&__new_val)
Assign __new_val to __obj and return its previous value.
bitset< _Nb > operator|(const bitset< _Nb > &__x, const bitset< _Nb > &__y) noexcept
Global bitwise operations on bitsets.
_Tp kill_dependency(_Tp __y) noexcept
kill_dependency
memory_order
Enumeration for memory_order.