165 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef _LIBCPP___ATOMIC_ATOMIC_FLAG_H10#define _LIBCPP___ATOMIC_ATOMIC_FLAG_H11 12#include <__atomic/atomic_sync.h>13#include <__atomic/contention_t.h>14#include <__atomic/memory_order.h>15#include <__atomic/support.h>16#include <__chrono/duration.h>17#include <__config>18#include <__memory/addressof.h>19#include <__thread/support.h>20#include <cstdint>21 22#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)23# pragma GCC system_header24#endif25 26_LIBCPP_BEGIN_NAMESPACE_STD27 28struct atomic_flag {29 __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_;30 31 _LIBCPP_HIDE_FROM_ABI bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT {32 return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);33 }34 _LIBCPP_HIDE_FROM_ABI bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT {35 return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);36 }37 38 _LIBCPP_HIDE_FROM_ABI bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {39 return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);40 }41 _LIBCPP_HIDE_FROM_ABI bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT {42 return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);43 }44 _LIBCPP_HIDE_FROM_ABI void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {45 __cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);46 }47 _LIBCPP_HIDE_FROM_ABI void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT {48 __cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);49 }50 51#if _LIBCPP_STD_VER >= 2052 _LIBCPP_HIDE_FROM_ABI void wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT {53 std::__atomic_wait(*this, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);54 }55 _LIBCPP_HIDE_FROM_ABI void wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT {56 std::__atomic_wait(*this, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);57 }58 _LIBCPP_HIDE_FROM_ABI void notify_one() volatile _NOEXCEPT { std::__atomic_notify_one(*this); }59 _LIBCPP_HIDE_FROM_ABI void notify_one() _NOEXCEPT { std::__atomic_notify_one(*this); }60 _LIBCPP_HIDE_FROM_ABI void notify_all() volatile _NOEXCEPT { std::__atomic_notify_all(*this); }61 _LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT { std::__atomic_notify_all(*this); }62#endif63 64#if _LIBCPP_STD_VER >= 2065 _LIBCPP_HIDE_FROM_ABI constexpr atomic_flag() _NOEXCEPT : __a_(false) {}66#else67 atomic_flag() _NOEXCEPT = default;68#endif69 70 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION71 72 atomic_flag(const atomic_flag&) = delete;73 atomic_flag& operator=(const atomic_flag&) = delete;74 atomic_flag& operator=(const atomic_flag&) volatile = delete;75};76 77template <>78struct __atomic_waitable_traits<atomic_flag> {79 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_ATOMIC_FLAG_TYPE __atomic_load(const atomic_flag& __a, memory_order __order) {80 return std::__cxx_atomic_load(&__a.__a_, __order);81 }82 83 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_ATOMIC_FLAG_TYPE84 __atomic_load(const volatile atomic_flag& __a, memory_order __order) {85 return std::__cxx_atomic_load(&__a.__a_, __order);86 }87 88 static _LIBCPP_HIDE_FROM_ABI const __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE>*89 __atomic_contention_address(const atomic_flag& __a) {90 return std::addressof(__a.__a_);91 }92 93 static _LIBCPP_HIDE_FROM_ABI const volatile __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE>*94 __atomic_contention_address(const volatile atomic_flag& __a) {95 return std::addressof(__a.__a_);96 }97};98 99inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT { return __o->test(); }100 101inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test(const atomic_flag* __o) _NOEXCEPT { return __o->test(); }102 103inline _LIBCPP_HIDE_FROM_ABI bool104atomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT {105 return __o->test(__m);106}107 108inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT {109 return __o->test(__m);110}111 112inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT {113 return __o->test_and_set();114}115 116inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT { return __o->test_and_set(); }117 118inline _LIBCPP_HIDE_FROM_ABI bool119atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT {120 return __o->test_and_set(__m);121}122 123inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT {124 return __o->test_and_set(__m);125}126 127inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT { __o->clear(); }128 129inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear(atomic_flag* __o) _NOEXCEPT { __o->clear(); }130 131inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT {132 __o->clear(__m);133}134 135inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT {136 __o->clear(__m);137}138 139#if _LIBCPP_STD_VER >= 20140inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT {141 __o->wait(__v);142}143 144inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT { __o->wait(__v); }145 146inline _LIBCPP_HIDE_FROM_ABI void147atomic_flag_wait_explicit(const volatile atomic_flag* __o, bool __v, memory_order __m) _NOEXCEPT {148 __o->wait(__v, __m);149}150 151inline _LIBCPP_HIDE_FROM_ABI void152atomic_flag_wait_explicit(const atomic_flag* __o, bool __v, memory_order __m) _NOEXCEPT {153 __o->wait(__v, __m);154}155 156inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT { __o->notify_one(); }157inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT { __o->notify_one(); }158inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT { __o->notify_all(); }159inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT { __o->notify_all(); }160#endif // _LIBCPP_STD_VER >= 20161 162_LIBCPP_END_NAMESPACE_STD163 164#endif // _LIBCPP___ATOMIC_ATOMIC_FLAG_H165