NexusForce 1.0.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
atomic_futex.hpp
浏览该文件的文档.
1#ifndef NEFORCE_CORE_ASYNC_ATOMIC_FUTEX_HPP__
2#define NEFORCE_CORE_ASYNC_ATOMIC_FUTEX_HPP__
3
11
14NEFORCE_BEGIN_NAMESPACE__
15
21
27
36template <uint32_t WaiterBit = 0x80000000>
38 atomic<uint32_t> data_;
39
52 uint32_t load_and_test_until(uint32_t assumed, const uint32_t operand, const bool equal, const memory_order mo,
53 const bool has_timeout, const int64_t sec, const int64_t ns) {
54 for (;;) {
55 data_.fetch_or(WaiterBit, memory_order_relaxed);
56 const bool ret = futex_wait_until(&data_, assumed | WaiterBit, has_timeout, sec, ns, false);
57 assumed = load(mo);
58 if (!ret || ((operand == assumed) == equal)) {
59 return assumed;
60 }
61 }
62 }
63
76 uint32_t load_and_test_until_steady(uint32_t assumed, const uint32_t operand, const bool equal,
77 const memory_order mo, const bool has_timeout, const int64_t sec,
78 const int64_t ns) {
79 for (;;) {
80 data_.fetch_or(WaiterBit, memory_order_relaxed);
81 const bool ret = futex_wait_until(&data_, assumed | WaiterBit, has_timeout, sec, ns, true);
82 assumed = load(mo);
83 if (!ret || ((operand == assumed) == equal)) {
84 return assumed;
85 }
86 }
87 }
88
97 uint32_t load_and_test(const uint32_t assumed, const uint32_t operand, const bool equal, const memory_order mo) {
98 return load_and_test_until(assumed, operand, equal, mo, false, 0, 0);
99 }
100
111 template <typename Dur>
112 uint32_t load_and_test_until_impl(uint32_t assumed, uint32_t operand, bool equal, memory_order mo,
113 const time_point<system_clock, Dur>& atime) {
114 auto sec = atime.to_sec();
115 const auto ns = nanoseconds(atime - sec).count();
116 return this->load_and_test_until(assumed, operand, equal, mo, true, sec.since_epoch().count(), ns);
117 }
118
129 template <typename Dur>
130 uint32_t load_and_test_until_impl(uint32_t assumed, uint32_t operand, bool equal, memory_order mo,
131 const time_point<steady_clock, Dur>& atime) {
132 auto sec = atime.to_sec();
133 const auto ns = nanoseconds(atime - sec).count();
134 return this->load_and_test_until_steady(assumed, operand, equal, mo, true, sec.since_epoch().count(), ns);
135 }
136
137public:
142 explicit atomic_futex(const uint32_t data) :
143 data_(data) {}
144
152 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE uint32_t load(const memory_order mo) const {
153 return data_.load(mo) & ~WaiterBit;
154 }
155
164 NEFORCE_ALWAYS_INLINE uint32_t load_when_not_equal(const uint32_t value, const memory_order mo) {
165 const uint32_t old = load(mo);
166 if ((old & ~WaiterBit) != value) {
167 return (old & ~WaiterBit);
168 }
169 return load_and_test(old, value, false, mo);
170 }
171
179 NEFORCE_ALWAYS_INLINE void load_when_equal(const uint32_t value, const memory_order mo) {
180 const uint32_t old = load(mo);
181 if ((old & ~WaiterBit) == value) {
182 return;
183 }
184 load_and_test(old, value, true, mo);
185 }
186
196 template <typename Rep, typename Period>
197 NEFORCE_ALWAYS_INLINE bool load_when_equal_for(const uint32_t value, const memory_order mo,
198 const duration<Rep, Period>& rtime) {
199 const auto atime = steady_clock::now() + ceil<steady_clock::duration>(rtime);
200 return this->load_when_equal_until(value, mo, atime);
201 }
202
214 template <typename Clock, typename Dur>
215 NEFORCE_ALWAYS_INLINE bool load_when_equal_until(const uint32_t value, const memory_order mo,
216 const time_point<Clock, Dur>& atime) {
217 auto now = Clock::now();
218 do {
219 const auto s_atime = steady_clock::now() + ceil<steady_clock::duration>(atime - now);
220 if (this->load_when_equal_until(value, mo, s_atime)) {
221 return true;
222 }
223 now = Clock::now();
224 } while (now < atime);
225 return false;
226 }
227
236 template <typename Dur>
237 NEFORCE_ALWAYS_INLINE bool load_when_equal_until(const uint32_t value, const memory_order mo,
238 const time_point<system_clock, Dur>& atime) {
239 uint32_t old = load(mo);
240 if ((old & ~WaiterBit) == value) {
241 return true;
242 }
243 old = this->load_and_test_until_impl(old, value, true, mo, atime);
244 return (old & ~WaiterBit) == value;
245 }
246
255 template <typename Dur>
256 NEFORCE_ALWAYS_INLINE bool load_when_equal_until(const uint32_t value, const memory_order mo,
257 const time_point<steady_clock, Dur>& atime) {
258 uint32_t old = load(mo);
259 if ((old & ~WaiterBit) == value) {
260 return true;
261 }
262 old = this->load_and_test_until_impl(old, value, true, mo, atime);
263 return (old & ~WaiterBit) == value;
264 }
265
273 NEFORCE_ALWAYS_INLINE void store_notify_all(const uint32_t value, const memory_order mo) {
274 const auto futex = static_cast<uint32_t*>(static_cast<void*>(&data_));
275 if (data_.exchange(value, mo) & WaiterBit) {
276 _NEFORCE futex_notify(futex, true);
277 }
278 }
279};
280 // Futex
282 // AsyncComponents
284
285NEFORCE_END_NAMESPACE__
286#endif // NEFORCE_CORE_ASYNC_ATOMIC_FUTEX_HPP__
原子类型完整实现
NEFORCE_ALWAYS_INLINE bool load_when_equal_until(const uint32_t value, const memory_order mo, const time_point< system_clock, Dur > &atime)
在指定时间点前等待值等于指定值(系统时钟)
NEFORCE_ALWAYS_INLINE void store_notify_all(const uint32_t value, const memory_order mo)
存储新值并通知所有等待线程
atomic_futex(const uint32_t data)
构造函数
NEFORCE_ALWAYS_INLINE bool load_when_equal_for(const uint32_t value, const memory_order mo, const duration< Rep, Period > &rtime)
在指定时间内等待值等于指定值
NEFORCE_ALWAYS_INLINE void load_when_equal(const uint32_t value, const memory_order mo)
等待直到值等于指定值
NEFORCE_ALWAYS_INLINE bool load_when_equal_until(const uint32_t value, const memory_order mo, const time_point< Clock, Dur > &atime)
在指定时间点前等待值等于指定值(通用时钟)
NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE uint32_t load(const memory_order mo) const
原子加载数据
NEFORCE_ALWAYS_INLINE uint32_t load_when_not_equal(const uint32_t value, const memory_order mo)
等待直到值不等于指定值
NEFORCE_ALWAYS_INLINE bool load_when_equal_until(const uint32_t value, const memory_order mo, const time_point< steady_clock, Dur > &atime)
在指定时间点前等待值等于指定值(单调时钟)
时钟类型
NEFORCE_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 NEFORCE_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定时等待函数
NEFORCE_CONST_FUNCTION NEFORCE_CONSTEXPR14 decimal_t ceil(const decimal_t x) noexcept
向上取整
NEFORCE_INLINE17 constexpr auto memory_order_relaxed
宽松内存顺序常量
memory_order
内存顺序
NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr decltype(auto) data(Container &cont) noexcept(noexcept(cont.data()))
获取容器的底层数据指针
通用原子类型模板
持续时间类模板
constexpr rep count() const noexcept
获取计数值
static time_point now() noexcept
获取当前时间点
时间点类模板