diff options
Diffstat (limited to 'libcxx/include/semaphore')
-rw-r--r-- | libcxx/include/semaphore | 193 |
1 files changed, 82 insertions, 111 deletions
diff --git a/libcxx/include/semaphore b/libcxx/include/semaphore index 81f3cd2a7945..de45b8b5db10 100644 --- a/libcxx/include/semaphore +++ b/libcxx/include/semaphore @@ -64,7 +64,7 @@ using binary_semaphore = counting_semaphore<1>; #endif #ifdef _LIBCPP_HAS_NO_THREADS -# error "<semaphore> is not supported since libc++ has been configured without support for threads." +# error "<semaphore> is not supported since libc++ has been configured without support for threads." #endif _LIBCPP_PUSH_MACROS @@ -82,124 +82,95 @@ functions. It avoids contention against users' own use of those facilities. */ -#define _LIBCPP_SEMAPHORE_MAX (numeric_limits<ptrdiff_t>::max()) +# define _LIBCPP_SEMAPHORE_MAX (numeric_limits<ptrdiff_t>::max()) -class __atomic_semaphore_base -{ - __atomic_base<ptrdiff_t> __a_; +class __atomic_semaphore_base { + __atomic_base<ptrdiff_t> __a_; public: - _LIBCPP_HIDE_FROM_ABI - constexpr explicit __atomic_semaphore_base(ptrdiff_t __count) : __a_(__count) - { - } - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI - void release(ptrdiff_t __update = 1) - { - auto __old = __a_.fetch_add(__update, memory_order_release); - _LIBCPP_ASSERT_UNCATEGORIZED(__update <= _LIBCPP_SEMAPHORE_MAX - __old, "update is greater than the expected value"); - - if (__old > 0) - { - // Nothing to do - } - else if (__update > 1) - __a_.notify_all(); - else - __a_.notify_one(); - } - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI - void acquire() - { - auto const __test_fn = [this]() -> bool { - auto __old = __a_.load(memory_order_relaxed); - return (__old != 0) && __a_.compare_exchange_strong(__old, __old - 1, memory_order_acquire, memory_order_relaxed); - }; - __cxx_atomic_wait(&__a_.__a_, __test_fn); - } - template <class _Rep, class _Period> - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI - bool try_acquire_for(chrono::duration<_Rep, _Period> const& __rel_time) - { - if (__rel_time == chrono::duration<_Rep, _Period>::zero()) - return try_acquire(); - auto const __test_fn = [this]() { return try_acquire(); }; - return std::__libcpp_thread_poll_with_backoff(__test_fn, __libcpp_timed_backoff_policy(), __rel_time); - } - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI - bool try_acquire() - { - auto __old = __a_.load(memory_order_acquire); - while (true) { - if (__old == 0) - return false; - if (__a_.compare_exchange_strong(__old, __old - 1, memory_order_acquire, memory_order_relaxed)) - return true; - } + _LIBCPP_HIDE_FROM_ABI constexpr explicit __atomic_semaphore_base(ptrdiff_t __count) : __a_(__count) {} + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void release(ptrdiff_t __update = 1) { + auto __old = __a_.fetch_add(__update, memory_order_release); + _LIBCPP_ASSERT_UNCATEGORIZED( + __update <= _LIBCPP_SEMAPHORE_MAX - __old, "update is greater than the expected value"); + + if (__old > 0) { + // Nothing to do + } else if (__update > 1) + __a_.notify_all(); + else + __a_.notify_one(); + } + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void acquire() { + auto const __test_fn = [this]() -> bool { + auto __old = __a_.load(memory_order_relaxed); + return (__old != 0) && __a_.compare_exchange_strong(__old, __old - 1, memory_order_acquire, memory_order_relaxed); + }; + __cxx_atomic_wait(&__a_.__a_, __test_fn); + } + template <class _Rep, class _Period> + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool + try_acquire_for(chrono::duration<_Rep, _Period> const& __rel_time) { + if (__rel_time == chrono::duration<_Rep, _Period>::zero()) + return try_acquire(); + auto const __test_fn = [this]() { return try_acquire(); }; + return std::__libcpp_thread_poll_with_backoff(__test_fn, __libcpp_timed_backoff_policy(), __rel_time); + } + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool try_acquire() { + auto __old = __a_.load(memory_order_acquire); + while (true) { + if (__old == 0) + return false; + if (__a_.compare_exchange_strong(__old, __old - 1, memory_order_acquire, memory_order_relaxed)) + return true; } + } }; -template<ptrdiff_t __least_max_value = _LIBCPP_SEMAPHORE_MAX> -class counting_semaphore -{ - __atomic_semaphore_base __semaphore_; +template <ptrdiff_t __least_max_value = _LIBCPP_SEMAPHORE_MAX> +class counting_semaphore { + __atomic_semaphore_base __semaphore_; public: - static_assert(__least_max_value >= 0, "The least maximum value must be a positive number"); - - static constexpr ptrdiff_t max() noexcept { - return __least_max_value; - } - - _LIBCPP_HIDE_FROM_ABI - constexpr explicit counting_semaphore(ptrdiff_t __count) : __semaphore_(__count) - { - _LIBCPP_ASSERT_UNCATEGORIZED( - __count >= 0, - "counting_semaphore::counting_semaphore(ptrdiff_t): counting_semaphore cannot be " - "initialized with a negative value"); - _LIBCPP_ASSERT_UNCATEGORIZED( - __count <= max(), - "counting_semaphore::counting_semaphore(ptrdiff_t): counting_semaphore cannot be " - "initialized with a value greater than max()"); - } - ~counting_semaphore() = default; - - counting_semaphore(const counting_semaphore&) = delete; - counting_semaphore& operator=(const counting_semaphore&) = delete; - - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI - void release(ptrdiff_t __update = 1) - { - _LIBCPP_ASSERT_UNCATEGORIZED(__update >= 0, "counting_semaphore:release called with a negative value"); - __semaphore_.release(__update); - } - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI - void acquire() - { - __semaphore_.acquire(); - } - template<class _Rep, class _Period> - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI - bool try_acquire_for(chrono::duration<_Rep, _Period> const& __rel_time) - { - return __semaphore_.try_acquire_for(chrono::duration_cast<chrono::nanoseconds>(__rel_time)); - } - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI - bool try_acquire() - { - return __semaphore_.try_acquire(); - } - template <class _Clock, class _Duration> - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI - bool try_acquire_until(chrono::time_point<_Clock, _Duration> const& __abs_time) - { - auto const __current = _Clock::now(); - if (__current >= __abs_time) - return try_acquire(); - else - return try_acquire_for(__abs_time - __current); - } + static_assert(__least_max_value >= 0, "The least maximum value must be a positive number"); + + static constexpr ptrdiff_t max() noexcept { return __least_max_value; } + + _LIBCPP_HIDE_FROM_ABI constexpr explicit counting_semaphore(ptrdiff_t __count) : __semaphore_(__count) { + _LIBCPP_ASSERT_UNCATEGORIZED( + __count >= 0, + "counting_semaphore::counting_semaphore(ptrdiff_t): counting_semaphore cannot be " + "initialized with a negative value"); + _LIBCPP_ASSERT_UNCATEGORIZED( + __count <= max(), + "counting_semaphore::counting_semaphore(ptrdiff_t): counting_semaphore cannot be " + "initialized with a value greater than max()"); + } + ~counting_semaphore() = default; + + counting_semaphore(const counting_semaphore&) = delete; + counting_semaphore& operator=(const counting_semaphore&) = delete; + + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void release(ptrdiff_t __update = 1) { + _LIBCPP_ASSERT_UNCATEGORIZED(__update >= 0, "counting_semaphore:release called with a negative value"); + __semaphore_.release(__update); + } + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void acquire() { __semaphore_.acquire(); } + template <class _Rep, class _Period> + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool + try_acquire_for(chrono::duration<_Rep, _Period> const& __rel_time) { + return __semaphore_.try_acquire_for(chrono::duration_cast<chrono::nanoseconds>(__rel_time)); + } + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool try_acquire() { return __semaphore_.try_acquire(); } + template <class _Clock, class _Duration> + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool + try_acquire_until(chrono::time_point<_Clock, _Duration> const& __abs_time) { + auto const __current = _Clock::now(); + if (__current >= __abs_time) + return try_acquire(); + else + return try_acquire_for(__abs_time - __current); + } }; using binary_semaphore = counting_semaphore<1>; |