MSTL 1.4.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
atomic_futex.hpp
浏览该文件的文档.
1#ifndef MSTL_CORE_ASYNC_ATOMIC_FUTEX_HPP__
2#define MSTL_CORE_ASYNC_ATOMIC_FUTEX_HPP__
3
11
15
21
30template <uint32_t WaiterBit = 0x80000000>
32 atomic<uint32_t> data_;
33
46 uint32_t load_and_test_until(uint32_t assumed, const uint32_t operand,
47 const bool equal, const memory_order mo, const bool has_timeout,
48 const int64_t sec, const int64_t ns) {
49 for (;;) {
50 data_.fetch_or(WaiterBit, memory_order_relaxed);
51 const bool ret = _MSTL futex_wait_until(
52 &data_, assumed | WaiterBit, has_timeout, sec, ns, false);
53 assumed = load(mo);
54 if (!ret || ((operand == assumed) == equal)) {
55 return assumed;
56 }
57 }
58 }
59
72 uint32_t load_and_test_until_steady(uint32_t assumed, const uint32_t operand,
73 const bool equal, const memory_order mo, const bool has_timeout,
74 const int64_t sec, const int64_t ns) {
75 for (;;) {
76 data_.fetch_or(WaiterBit, memory_order_relaxed);
77 const bool ret = _MSTL futex_wait_until(
78 &data_, assumed | WaiterBit, has_timeout, sec, ns, true);
79 assumed = load(mo);
80 if (!ret || ((operand == assumed) == equal)) {
81 return assumed;
82 }
83 }
84 }
85
94 uint32_t load_and_test(const uint32_t assumed, const uint32_t operand,
95 const bool equal, const memory_order mo) {
96 return load_and_test_until(
97 assumed, operand, equal, mo, false, 0, 0);
98 }
99
110 template <typename Dur>
111 uint32_t load_and_test_until_impl(
112 uint32_t assumed, uint32_t operand,
113 bool equal, memory_order mo,
114 const time_point<system_clock, Dur>& atime) {
115 auto sec = atime.to_sec();
116 const auto ns = nanoseconds(atime - sec).count();
117 return this->load_and_test_until(
118 assumed, operand, equal, mo,
119 true, sec.since_epoch().count(), ns);
120 }
121
132 template <typename Dur>
133 uint32_t load_and_test_until_impl(
134 uint32_t assumed, uint32_t operand,
135 bool equal, memory_order mo,
136 const time_point<steady_clock, Dur>& atime) {
137 auto sec = atime.to_sec();
138 const auto ns = nanoseconds(atime - sec).count();
139 return this->load_and_test_until_steady(
140 assumed, operand, equal, mo,
141 true, sec.since_epoch().count(), ns);
142 }
143
144public:
149 explicit atomic_futex(const uint32_t data)
150 : data_(data) {}
151
159 MSTL_NODISCARD MSTL_ALWAYS_INLINE uint32_t
160 load(const memory_order mo) const {
161 return data_.load(mo) & ~WaiterBit;
162 }
163
172 MSTL_ALWAYS_INLINE uint32_t
174 const uint32_t old = load(mo);
175 if ((old & ~WaiterBit) != value) {
176 return (old & ~WaiterBit);
177 }
178 return load_and_test(old, value, false, mo);
179 }
180
188 MSTL_ALWAYS_INLINE void
189 load_when_equal(const uint32_t value, const memory_order mo) {
190 const uint32_t old = load(mo);
191 if ((old & ~WaiterBit) == value) {
192 return;
193 }
194 load_and_test(old, value, true, mo);
195 }
196
206 template <typename Rep, typename Period>
207 MSTL_ALWAYS_INLINE bool
209 const duration<Rep, Period>& rtime) {
210 const auto atime = steady_clock::now() + ceil<steady_clock::duration>(rtime);
211 return this->load_when_equal_until(value, mo, atime);
212 }
213
225 template <typename Clock, typename Dur>
226 MSTL_ALWAYS_INLINE bool
228 const time_point<Clock, Dur>& atime) {
229 auto now = Clock::now();
230 do {
231 const auto s_atime = steady_clock::now() + _MSTL ceil<steady_clock::duration>(atime - now);
232 if (this->load_when_equal_until(value, mo, s_atime)) {
233 return true;
234 }
235 now = Clock::now();
236 } while (now < atime);
237 return false;
238 }
239
248 template <typename Dur>
249 MSTL_ALWAYS_INLINE bool
251 const time_point<system_clock, Dur>& atime) {
252 uint32_t old = load(mo);
253 if ((old & ~WaiterBit) == value) {
254 return true;
255 }
256 old = this->load_and_test_until_impl(old, value, true, mo, atime);
257 return (old & ~WaiterBit) == value;
258 }
259
268 template <typename Dur>
269 MSTL_ALWAYS_INLINE bool
271 const time_point<steady_clock, Dur>& atime) {
272 uint32_t old = load(mo);
273 if ((old & ~WaiterBit) == value) {
274 return true;
275 }
276 old = this->load_and_test_until_impl(old, value, true, mo, atime);
277 return (old & ~WaiterBit) == value;
278 }
279
287 MSTL_ALWAYS_INLINE void store_notify_all(const uint32_t value, const memory_order mo) {
288 const auto futex = static_cast<uint32_t*>(static_cast<void*>(&data_));
289 if (data_.exchange(value, mo) & WaiterBit) {
290 _MSTL futex_notify(futex, true);
291 }
292 }
293};
294 // Futex
296
298#endif // MSTL_CORE_ASYNC_ATOMIC_FUTEX_HPP__
MSTL原子类型完整实现
MSTL_ALWAYS_INLINE bool load_when_equal_until(const uint32_t value, const memory_order mo, const time_point< steady_clock, Dur > &atime)
在指定时间点前等待值等于指定值(单调时钟)
MSTL_ALWAYS_INLINE bool load_when_equal_for(const uint32_t value, const memory_order mo, const duration< Rep, Period > &rtime)
在指定时间内等待值等于指定值
MSTL_ALWAYS_INLINE void store_notify_all(const uint32_t value, const memory_order mo)
存储新值并通知所有等待线程
atomic_futex(const uint32_t data)
构造函数
MSTL_ALWAYS_INLINE void load_when_equal(const uint32_t value, const memory_order mo)
等待直到值等于指定值
MSTL_ALWAYS_INLINE bool load_when_equal_until(const uint32_t value, const memory_order mo, const time_point< system_clock, Dur > &atime)
在指定时间点前等待值等于指定值(系统时钟)
MSTL_ALWAYS_INLINE uint32_t load_when_not_equal(const uint32_t value, const memory_order mo)
等待直到值不等于指定值
MSTL_ALWAYS_INLINE bool load_when_equal_until(const uint32_t value, const memory_order mo, const time_point< Clock, Dur > &atime)
在指定时间点前等待值等于指定值(通用时钟)
MSTL_NODISCARD MSTL_ALWAYS_INLINE uint32_t load(const memory_order mo) const
原子加载数据
MSTL时钟类型
MSTL_NODISCARD constexpr bool equal(Iterator1 first1, Iterator1 last1, Iterator2 first2, BinaryPredicate binary_pred) noexcept(noexcept(++first1) &&noexcept(++first2) &&noexcept(binary_pred(*first1, *first2)))
比较两个范围是否相等
unsigned int uint32_t
32位无符号整数类型
long long int64_t
64位有符号整数类型
duration< int64_t, nano > nanoseconds
纳秒持续时间
void MSTL_API futex_notify(void *addr, bool all) noexcept
通知等待的线程
bool futex_wait_until(const platform_wait_t *addr, platform_wait_t old, const time_point< Clock, Dur > &timeout)
FUTEX定时等待函数
MSTL_CONST_FUNCTION MSTL_CONSTEXPR14 decimal_t ceil(const decimal_t x) noexcept
向上取整
MSTL_INLINE17 constexpr auto memory_order_relaxed
宽松内存顺序常量
memory_order
内存顺序
#define _MSTL
全局命名空间MSTL前缀
#define MSTL_END_NAMESPACE__
结束全局命名空间MSTL
#define MSTL_BEGIN_NAMESPACE__
开始全局命名空间MSTL
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr decltype(auto) data(Container &cont) noexcept(noexcept(cont.data()))
获取容器的底层数据指针
通用原子类型模板
持续时间类模板
constexpr rep count() const noexcept
获取计数值
static time_point now() noexcept
获取当前时间点
时间点类模板