atomic_flag.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. //===----------------------------------------------------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #ifndef _LIBCPP___ATOMIC_ATOMIC_FLAG_H
  9. #define _LIBCPP___ATOMIC_ATOMIC_FLAG_H
  10. #include <__atomic/atomic_sync.h>
  11. #include <__atomic/contention_t.h>
  12. #include <__atomic/cxx_atomic_impl.h>
  13. #include <__atomic/memory_order.h>
  14. #include <__availability>
  15. #include <__chrono/duration.h>
  16. #include <__config>
  17. #include <__memory/addressof.h>
  18. #include <__thread/support.h>
  19. #include <cstdint>
  20. #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
  21. # pragma GCC system_header
  22. #endif
  23. _LIBCPP_BEGIN_NAMESPACE_STD
  24. struct atomic_flag {
  25. __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_;
  26. _LIBCPP_HIDE_FROM_ABI bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT {
  27. return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);
  28. }
  29. _LIBCPP_HIDE_FROM_ABI bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT {
  30. return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);
  31. }
  32. _LIBCPP_HIDE_FROM_ABI bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
  33. return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);
  34. }
  35. _LIBCPP_HIDE_FROM_ABI bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT {
  36. return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);
  37. }
  38. _LIBCPP_HIDE_FROM_ABI void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
  39. __cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);
  40. }
  41. _LIBCPP_HIDE_FROM_ABI void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT {
  42. __cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);
  43. }
  44. _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void wait(bool __v, memory_order __m = memory_order_seq_cst) const
  45. volatile _NOEXCEPT {
  46. std::__atomic_wait(*this, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);
  47. }
  48. _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
  49. wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT {
  50. std::__atomic_wait(*this, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);
  51. }
  52. _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() volatile _NOEXCEPT {
  53. std::__atomic_notify_one(*this);
  54. }
  55. _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() _NOEXCEPT { std::__atomic_notify_one(*this); }
  56. _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() volatile _NOEXCEPT {
  57. std::__atomic_notify_all(*this);
  58. }
  59. _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT { std::__atomic_notify_all(*this); }
  60. #if _LIBCPP_STD_VER >= 20
  61. _LIBCPP_HIDE_FROM_ABI constexpr atomic_flag() _NOEXCEPT : __a_(false) {}
  62. #else
  63. atomic_flag() _NOEXCEPT = default;
  64. #endif
  65. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION
  66. atomic_flag(const atomic_flag&) = delete;
  67. atomic_flag& operator=(const atomic_flag&) = delete;
  68. atomic_flag& operator=(const atomic_flag&) volatile = delete;
  69. };
  70. template <>
  71. struct __atomic_waitable_traits<atomic_flag> {
  72. static _LIBCPP_HIDE_FROM_ABI _LIBCPP_ATOMIC_FLAG_TYPE __atomic_load(const atomic_flag& __a, memory_order __order) {
  73. return std::__cxx_atomic_load(&__a.__a_, __order);
  74. }
  75. static _LIBCPP_HIDE_FROM_ABI _LIBCPP_ATOMIC_FLAG_TYPE
  76. __atomic_load(const volatile atomic_flag& __a, memory_order __order) {
  77. return std::__cxx_atomic_load(&__a.__a_, __order);
  78. }
  79. static _LIBCPP_HIDE_FROM_ABI const __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE>*
  80. __atomic_contention_address(const atomic_flag& __a) {
  81. return std::addressof(__a.__a_);
  82. }
  83. static _LIBCPP_HIDE_FROM_ABI const volatile __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE>*
  84. __atomic_contention_address(const volatile atomic_flag& __a) {
  85. return std::addressof(__a.__a_);
  86. }
  87. };
  88. inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT { return __o->test(); }
  89. inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test(const atomic_flag* __o) _NOEXCEPT { return __o->test(); }
  90. inline _LIBCPP_HIDE_FROM_ABI bool
  91. atomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT {
  92. return __o->test(__m);
  93. }
  94. inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT {
  95. return __o->test(__m);
  96. }
  97. inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT {
  98. return __o->test_and_set();
  99. }
  100. inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT { return __o->test_and_set(); }
  101. inline _LIBCPP_HIDE_FROM_ABI bool
  102. atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT {
  103. return __o->test_and_set(__m);
  104. }
  105. inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT {
  106. return __o->test_and_set(__m);
  107. }
  108. inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT { __o->clear(); }
  109. inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear(atomic_flag* __o) _NOEXCEPT { __o->clear(); }
  110. inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT {
  111. __o->clear(__m);
  112. }
  113. inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT {
  114. __o->clear(__m);
  115. }
  116. inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
  117. atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT {
  118. __o->wait(__v);
  119. }
  120. inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
  121. atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT {
  122. __o->wait(__v);
  123. }
  124. inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
  125. atomic_flag_wait_explicit(const volatile atomic_flag* __o, bool __v, memory_order __m) _NOEXCEPT {
  126. __o->wait(__v, __m);
  127. }
  128. inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
  129. atomic_flag_wait_explicit(const atomic_flag* __o, bool __v, memory_order __m) _NOEXCEPT {
  130. __o->wait(__v, __m);
  131. }
  132. inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
  133. atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT {
  134. __o->notify_one();
  135. }
  136. inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT {
  137. __o->notify_one();
  138. }
  139. inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
  140. atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT {
  141. __o->notify_all();
  142. }
  143. inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT {
  144. __o->notify_all();
  145. }
  146. _LIBCPP_END_NAMESPACE_STD
  147. #endif // _LIBCPP___ATOMIC_ATOMIC_FLAG_H