NexusForce 1.0.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
semaphore.hpp
浏览该文件的文档.
1#ifndef NEFORCE_CORE_ASYNC_SEMAPHORE_HPP__
2#define NEFORCE_CORE_ASYNC_SEMAPHORE_HPP__
3
13
14#include "atomic_base.hpp"
15#include "atomic_timed_wait.hpp"
16#ifdef NEFORCE_PLATFORM_LINUX
17# include <bits/local_lim.h>
18# include <semaphore.h>
19#endif
20NEFORCE_BEGIN_NAMESPACE__
21
27
33
47template <platform_wait_t LeastMaxValue = numeric_traits<platform_wait_t>::max()>
49 static_assert(LeastMaxValue >= 0, "LeastMaxValue should be upper than zero.");
50
51 alignas(alignof(platform_wait_t)) platform_wait_t counter_;
52
60 NEFORCE_ALWAYS_INLINE bool do_try_acquire() noexcept {
61 auto old_value = _NEFORCE atomic_load(&counter_, memory_order_acquire);
62 if (old_value == 0) {
63 return false;
64 }
65 return _NEFORCE atomic_cmpexch_strong(&counter_, &old_value, old_value - 1, memory_order_acquire,
67 }
68
69public:
77 explicit atomic_semaphore(const platform_wait_t desired) noexcept :
78 counter_(desired) {
79 NEFORCE_CONSTEXPR_ASSERT(desired >= 0);
80 }
81
82 ~atomic_semaphore() = default;
83
84 atomic_semaphore(const atomic_semaphore&) = delete;
85 atomic_semaphore& operator=(const atomic_semaphore&) = delete;
86
91 static constexpr platform_wait_t max() noexcept { return LeastMaxValue; }
92
99 void release(const platform_wait_t update = 1) noexcept {
100 if (0 < _NEFORCE atomic_fetch_add(&counter_, update, memory_order_release)) {
101 return;
102 }
103 _NEFORCE atomic_notify_address(&counter_, true);
104 }
105
111 void acquire() noexcept {
112 auto const pred = [this] { return this->do_try_acquire(); };
113 _NEFORCE atomic_wait_address(&counter_, pred);
114 }
115
122 bool try_acquire() noexcept {
123 auto const pred = [this] { return this->do_try_acquire(); };
124 return _NEFORCE atomic_spin(pred, [] { return false; });
125 }
126
137 template <typename Rep, typename Period>
138 bool try_acquire_for(const duration<Rep, Period>& relative) noexcept {
139 auto const pred = [this] { return this->do_try_acquire(); };
140 return _NEFORCE atomic_wait_address_for(&counter_, pred, relative);
141 }
142
152 template <typename Clock, typename Dur>
154 auto const pred = [this] { return this->do_try_acquire(); };
155 return _NEFORCE atomic_wait_address_until(&counter_, pred, timeout);
156 }
157};
158
166
167
175class NEFORCE_API semaphore {
176public:
177#ifdef NEFORCE_PLATFORM_WINDOWS
178 static constexpr long max_count = numeric_traits<long>::max();
179 using native_handle_type = ::HANDLE;
180#else
181 static constexpr int max_count = SEM_VALUE_MAX;
182 using native_handle_type = ::sem_t;
183#endif
184
185private:
186#ifdef NEFORCE_PLATFORM_WINDOWS
187 ::HANDLE handle_ = nullptr;
188#else
189 ::sem_t sem_{};
190#endif
191
192#ifdef NEFORCE_PLATFORM_WINDOWS
193 bool try_acquire_for_impl(milliseconds timeout) noexcept;
194#else
195 bool try_acquire_for_impl(nanoseconds timeout) noexcept;
196#endif
197
198public:
205 explicit semaphore(long initial = 0, long maximum = max_count);
206
210 ~semaphore() noexcept;
211
212 semaphore(const semaphore&) = delete;
213 semaphore& operator=(const semaphore&) = delete;
214 semaphore(semaphore&&) = delete;
215 semaphore& operator=(semaphore&&) = delete;
216
223 void acquire() noexcept;
224
232 bool try_acquire() noexcept;
233
244 template <typename Rep, typename Period>
245 bool try_acquire_for(const duration<Rep, Period>& relative) noexcept {
246#ifdef NEFORCE_PLATFORM_WINDOWS
247 return semaphore::try_acquire_for_impl(_NEFORCE time_cast<milliseconds>(relative));
248#else
249 return semaphore::try_acquire_for_impl(_NEFORCE time_cast<nanoseconds>(relative));
250#endif
251 }
252
263 template <typename Clock, typename Dur>
265 auto now = Clock::now();
266 if (timeout <= now) {
267 return try_acquire();
268 }
269 return try_acquire_for(timeout - now);
270 }
271
279 void release(long update = 1);
280
288 int value() const noexcept;
289};
290 // Semaphores
292 // AsyncComponents
294
295NEFORCE_END_NAMESPACE__
296#endif // NEFORCE_CORE_ASYNC_SEMAPHORE_HPP__
原子操作基本工具
带超时的原子等待机制
原子信号量类模板
bool try_acquire_for(const duration< Rep, Period > &relative) noexcept
在指定时间内尝试获取信号量
bool try_acquire() noexcept
尝试获取信号量
void acquire() noexcept
获取信号量
static constexpr platform_wait_t max() noexcept
获取信号量的最大可能值
void release(const platform_wait_t update=1) noexcept
释放信号量
atomic_semaphore(const platform_wait_t desired) noexcept
构造函数
~atomic_semaphore()=default
析构函数
bool try_acquire_until(const time_point< Clock, Dur > &timeout) noexcept
在指定时间点前尝试获取信号量
static NEFORCE_NODISCARD constexpr T max() noexcept
获取类型的最大值
void release(long update=1)
释放信号量
semaphore(long initial=0, long maximum=max_count)
构造系统级信号量
bool try_acquire() noexcept
非阻塞尝试获取信号量
~semaphore() noexcept
析构函数,释放系统资源
int value() const noexcept
查询当前信号量计数值
bool try_acquire_for(const duration< Rep, Period > &relative) noexcept
在相对超时时间内尝试获取信号量
void acquire() noexcept
阻塞获取信号量
bool try_acquire_until(const time_point< Clock, Dur > &timeout) noexcept
在绝对时间点前尝试获取信号量
void atomic_wait_address(const T *addr, Pred pred) noexcept
基于谓词的原子等待
NEFORCE_ALWAYS_INLINE_INLINE remove_volatile_t< T > atomic_fetch_add(volatile T *ptr, atomic_diff_t< T > value, const memory_order mo) noexcept
原子获取并添加操作
bool atomic_spin(Pred &pred, Spin spin=Spin{}) noexcept
原子自旋等待
NEFORCE_ALWAYS_INLINE_INLINE bool atomic_cmpexch_strong(volatile T *ptr, remove_volatile_t< T > *expected, remove_volatile_t< T > desired, const memory_order success, const memory_order failure) noexcept
强比较交换操作
void atomic_notify_address(const T *addr, const bool all) noexcept
原子通知
bool atomic_wait_address_until(const T *addr, Pred pred, const time_point< Clock, Dur > &timeout) noexcept
基于谓词的原子定时等待(绝对时间)
bool atomic_wait_address_for(const T *addr, Pred pred, const duration< Rep, Period > &rt) noexcept
基于谓词的原子定时等待(相对时间)
NEFORCE_ALWAYS_INLINE_INLINE remove_volatile_t< T > atomic_load(const volatile T *ptr, const memory_order mo) noexcept
原子加载操作
#define NEFORCE_CONSTEXPR_ASSERT(COND)
编译时常量断言
duration< int64_t, milli > milliseconds
毫秒持续时间
duration< int64_t, nano > nanoseconds
纳秒持续时间
constexpr ToDur time_cast(const duration< Rep, Period > &value)
持续时间类型转换
int platform_wait_t
平台等待类型别名
NEFORCE_INLINE17 constexpr auto memory_order_release
释放内存顺序常量
NEFORCE_INLINE17 constexpr auto memory_order_relaxed
宽松内存顺序常量
NEFORCE_INLINE17 constexpr auto memory_order_acquire
获取内存顺序常量
atomic_semaphore< 1 > binary_semaphore
二元信号量
持续时间类模板
时间点类模板