diff options
author | Andrey Khalyavin <halyavin@gmail.com> | 2022-02-10 16:46:29 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:46:29 +0300 |
commit | f773626848a7c7456803654292e716b83d69cc12 (patch) | |
tree | db052dfcf9134f492bdbb962cb6c16cea58e1ed3 /contrib/libs/cxxsupp/libcxx/include/semaphore | |
parent | f43ab775d197d300eb67bd4497632b909cd7c2a5 (diff) | |
download | ydb-f773626848a7c7456803654292e716b83d69cc12.tar.gz |
Restoring authorship annotation for Andrey Khalyavin <halyavin@gmail.com>. Commit 1 of 2.
Diffstat (limited to 'contrib/libs/cxxsupp/libcxx/include/semaphore')
-rw-r--r-- | contrib/libs/cxxsupp/libcxx/include/semaphore | 480 |
1 files changed, 240 insertions, 240 deletions
diff --git a/contrib/libs/cxxsupp/libcxx/include/semaphore b/contrib/libs/cxxsupp/libcxx/include/semaphore index 4f9ecd0461..e49af03e42 100644 --- a/contrib/libs/cxxsupp/libcxx/include/semaphore +++ b/contrib/libs/cxxsupp/libcxx/include/semaphore @@ -1,240 +1,240 @@ -// -*- C++ -*- -//===--------------------------- semaphore --------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP_SEMAPHORE -#define _LIBCPP_SEMAPHORE - -/* - semaphore synopsis - -namespace std { - -template<ptrdiff_t least_max_value = implementation-defined> -class counting_semaphore -{ -public: -static constexpr ptrdiff_t max() noexcept; - -constexpr explicit counting_semaphore(ptrdiff_t desired); -~counting_semaphore(); - -counting_semaphore(const counting_semaphore&) = delete; -counting_semaphore& operator=(const counting_semaphore&) = delete; - -void release(ptrdiff_t update = 1); -void acquire(); -bool try_acquire() noexcept; -template<class Rep, class Period> - bool try_acquire_for(const chrono::duration<Rep, Period>& rel_time); -template<class Clock, class Duration> - bool try_acquire_until(const chrono::time_point<Clock, Duration>& abs_time); - -private: -ptrdiff_t counter; // exposition only -}; - -using binary_semaphore = counting_semaphore<1>; - -} - -*/ - -#include <__availability> -#include <__config> -#include <__threading_support> -#include <atomic> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header -#endif - -#ifdef _LIBCPP_HAS_NO_THREADS -# error <semaphore> is not supported on this single threaded system -#endif - -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - -#if _LIBCPP_STD_VER >= 14 - -_LIBCPP_BEGIN_NAMESPACE_STD - -/* - -__atomic_semaphore_base is the general-case implementation, to be used for -user-requested least-max values that exceed the OS implementation support -(incl. when the OS has no support of its own) and for binary semaphores. - -It is a typical Dijkstra semaphore algorithm over atomics, wait and notify -functions. It avoids contention against users' own use of those facilities. - -*/ - -class __atomic_semaphore_base -{ - __atomic_base<ptrdiff_t> __a; - -public: - _LIBCPP_INLINE_VISIBILITY - constexpr explicit __atomic_semaphore_base(ptrdiff_t __count) : __a(__count) - { - } - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY - void release(ptrdiff_t __update = 1) - { - if(0 < __a.fetch_add(__update, memory_order_release)) - ; - else if(__update > 1) - __a.notify_all(); - else - __a.notify_one(); - } - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY - 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_INLINE_VISIBILITY - bool try_acquire_for(chrono::duration<Rep, Period> const& __rel_time) - { - auto const __test_fn = [this]() -> bool { - auto __old = __a.load(memory_order_acquire); - while(1) { - if (__old == 0) - return false; - if(__a.compare_exchange_strong(__old, __old - 1, memory_order_acquire, memory_order_relaxed)) - return true; - } - }; - return __libcpp_thread_poll_with_backoff(__test_fn, __libcpp_timed_backoff_policy(), __rel_time); - } -}; - -#ifndef _LIBCPP_NO_NATIVE_SEMAPHORES - -/* - -__platform_semaphore_base a simple wrapper for the OS semaphore type. That -is, every call is routed to the OS in the most direct manner possible. - -*/ - -class __platform_semaphore_base -{ - __libcpp_semaphore_t __semaphore; - -public: - _LIBCPP_INLINE_VISIBILITY - explicit __platform_semaphore_base(ptrdiff_t __count) : - __semaphore() - { - __libcpp_semaphore_init(&__semaphore, __count); - } - _LIBCPP_INLINE_VISIBILITY - ~__platform_semaphore_base() { - __libcpp_semaphore_destroy(&__semaphore); - } - _LIBCPP_INLINE_VISIBILITY - void release(ptrdiff_t __update) - { - for(; __update; --__update) - __libcpp_semaphore_post(&__semaphore); - } - _LIBCPP_INLINE_VISIBILITY - void acquire() - { - __libcpp_semaphore_wait(&__semaphore); - } - _LIBCPP_INLINE_VISIBILITY - bool try_acquire_for(chrono::nanoseconds __rel_time) - { - return __libcpp_semaphore_wait_timed(&__semaphore, __rel_time); - } -}; - -template<ptrdiff_t __least_max_value> -using __semaphore_base = - typename conditional<(__least_max_value > 1 && __least_max_value <= _LIBCPP_SEMAPHORE_MAX), - __platform_semaphore_base, - __atomic_semaphore_base>::type; - -#else - -template<ptrdiff_t __least_max_value> -using __semaphore_base = - __atomic_semaphore_base; - -#define _LIBCPP_SEMAPHORE_MAX (numeric_limits<ptrdiff_t>::max()) - -#endif //_LIBCPP_NO_NATIVE_SEMAPHORES - -template<ptrdiff_t __least_max_value = _LIBCPP_SEMAPHORE_MAX> -class counting_semaphore -{ - __semaphore_base<__least_max_value> __semaphore; - -public: - static constexpr ptrdiff_t max() noexcept { - return __least_max_value; - } - - _LIBCPP_INLINE_VISIBILITY - constexpr explicit counting_semaphore(ptrdiff_t __count) : __semaphore(__count) { } - ~counting_semaphore() = default; - - counting_semaphore(const counting_semaphore&) = delete; - counting_semaphore& operator=(const counting_semaphore&) = delete; - - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY - void release(ptrdiff_t __update = 1) - { - __semaphore.release(__update); - } - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY - void acquire() - { - __semaphore.acquire(); - } - template<class Rep, class Period> - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY - 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_INLINE_VISIBILITY - bool try_acquire() - { - return try_acquire_for(chrono::nanoseconds::zero()); - } - template <class Clock, class Duration> - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY - 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>; - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP_STD_VER >= 14 - -_LIBCPP_POP_MACROS - -#endif //_LIBCPP_SEMAPHORE +// -*- C++ -*- +//===--------------------------- semaphore --------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_SEMAPHORE +#define _LIBCPP_SEMAPHORE + +/* + semaphore synopsis + +namespace std { + +template<ptrdiff_t least_max_value = implementation-defined> +class counting_semaphore +{ +public: +static constexpr ptrdiff_t max() noexcept; + +constexpr explicit counting_semaphore(ptrdiff_t desired); +~counting_semaphore(); + +counting_semaphore(const counting_semaphore&) = delete; +counting_semaphore& operator=(const counting_semaphore&) = delete; + +void release(ptrdiff_t update = 1); +void acquire(); +bool try_acquire() noexcept; +template<class Rep, class Period> + bool try_acquire_for(const chrono::duration<Rep, Period>& rel_time); +template<class Clock, class Duration> + bool try_acquire_until(const chrono::time_point<Clock, Duration>& abs_time); + +private: +ptrdiff_t counter; // exposition only +}; + +using binary_semaphore = counting_semaphore<1>; + +} + +*/ + +#include <__availability> +#include <__config> +#include <__threading_support> +#include <atomic> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#ifdef _LIBCPP_HAS_NO_THREADS +# error <semaphore> is not supported on this single threaded system +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +#if _LIBCPP_STD_VER >= 14 + +_LIBCPP_BEGIN_NAMESPACE_STD + +/* + +__atomic_semaphore_base is the general-case implementation, to be used for +user-requested least-max values that exceed the OS implementation support +(incl. when the OS has no support of its own) and for binary semaphores. + +It is a typical Dijkstra semaphore algorithm over atomics, wait and notify +functions. It avoids contention against users' own use of those facilities. + +*/ + +class __atomic_semaphore_base +{ + __atomic_base<ptrdiff_t> __a; + +public: + _LIBCPP_INLINE_VISIBILITY + constexpr explicit __atomic_semaphore_base(ptrdiff_t __count) : __a(__count) + { + } + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY + void release(ptrdiff_t __update = 1) + { + if(0 < __a.fetch_add(__update, memory_order_release)) + ; + else if(__update > 1) + __a.notify_all(); + else + __a.notify_one(); + } + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY + 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_INLINE_VISIBILITY + bool try_acquire_for(chrono::duration<Rep, Period> const& __rel_time) + { + auto const __test_fn = [this]() -> bool { + auto __old = __a.load(memory_order_acquire); + while(1) { + if (__old == 0) + return false; + if(__a.compare_exchange_strong(__old, __old - 1, memory_order_acquire, memory_order_relaxed)) + return true; + } + }; + return __libcpp_thread_poll_with_backoff(__test_fn, __libcpp_timed_backoff_policy(), __rel_time); + } +}; + +#ifndef _LIBCPP_NO_NATIVE_SEMAPHORES + +/* + +__platform_semaphore_base a simple wrapper for the OS semaphore type. That +is, every call is routed to the OS in the most direct manner possible. + +*/ + +class __platform_semaphore_base +{ + __libcpp_semaphore_t __semaphore; + +public: + _LIBCPP_INLINE_VISIBILITY + explicit __platform_semaphore_base(ptrdiff_t __count) : + __semaphore() + { + __libcpp_semaphore_init(&__semaphore, __count); + } + _LIBCPP_INLINE_VISIBILITY + ~__platform_semaphore_base() { + __libcpp_semaphore_destroy(&__semaphore); + } + _LIBCPP_INLINE_VISIBILITY + void release(ptrdiff_t __update) + { + for(; __update; --__update) + __libcpp_semaphore_post(&__semaphore); + } + _LIBCPP_INLINE_VISIBILITY + void acquire() + { + __libcpp_semaphore_wait(&__semaphore); + } + _LIBCPP_INLINE_VISIBILITY + bool try_acquire_for(chrono::nanoseconds __rel_time) + { + return __libcpp_semaphore_wait_timed(&__semaphore, __rel_time); + } +}; + +template<ptrdiff_t __least_max_value> +using __semaphore_base = + typename conditional<(__least_max_value > 1 && __least_max_value <= _LIBCPP_SEMAPHORE_MAX), + __platform_semaphore_base, + __atomic_semaphore_base>::type; + +#else + +template<ptrdiff_t __least_max_value> +using __semaphore_base = + __atomic_semaphore_base; + +#define _LIBCPP_SEMAPHORE_MAX (numeric_limits<ptrdiff_t>::max()) + +#endif //_LIBCPP_NO_NATIVE_SEMAPHORES + +template<ptrdiff_t __least_max_value = _LIBCPP_SEMAPHORE_MAX> +class counting_semaphore +{ + __semaphore_base<__least_max_value> __semaphore; + +public: + static constexpr ptrdiff_t max() noexcept { + return __least_max_value; + } + + _LIBCPP_INLINE_VISIBILITY + constexpr explicit counting_semaphore(ptrdiff_t __count) : __semaphore(__count) { } + ~counting_semaphore() = default; + + counting_semaphore(const counting_semaphore&) = delete; + counting_semaphore& operator=(const counting_semaphore&) = delete; + + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY + void release(ptrdiff_t __update = 1) + { + __semaphore.release(__update); + } + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY + void acquire() + { + __semaphore.acquire(); + } + template<class Rep, class Period> + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY + 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_INLINE_VISIBILITY + bool try_acquire() + { + return try_acquire_for(chrono::nanoseconds::zero()); + } + template <class Clock, class Duration> + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY + 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>; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER >= 14 + +_LIBCPP_POP_MACROS + +#endif //_LIBCPP_SEMAPHORE |