diff options
author | Andrey Khalyavin <halyavin@gmail.com> | 2022-02-10 16:46:30 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:46:30 +0300 |
commit | 4b839d0704ee9be1dabb0310a1f03af24963637b (patch) | |
tree | 1a2c5ffcf89eb53ecd79dbc9bc0a195c27404d0c /contrib/libs/cxxsupp/libcxx/src/thread.cpp | |
parent | f773626848a7c7456803654292e716b83d69cc12 (diff) | |
download | ydb-4b839d0704ee9be1dabb0310a1f03af24963637b.tar.gz |
Restoring authorship annotation for Andrey Khalyavin <halyavin@gmail.com>. Commit 2 of 2.
Diffstat (limited to 'contrib/libs/cxxsupp/libcxx/src/thread.cpp')
-rw-r--r-- | contrib/libs/cxxsupp/libcxx/src/thread.cpp | 416 |
1 files changed, 208 insertions, 208 deletions
diff --git a/contrib/libs/cxxsupp/libcxx/src/thread.cpp b/contrib/libs/cxxsupp/libcxx/src/thread.cpp index 268bae5829..8dddb240b5 100644 --- a/contrib/libs/cxxsupp/libcxx/src/thread.cpp +++ b/contrib/libs/cxxsupp/libcxx/src/thread.cpp @@ -1,211 +1,211 @@ -//===------------------------- thread.cpp----------------------------------===// -// +//===------------------------- thread.cpp----------------------------------===// +// // 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 -// -//===----------------------------------------------------------------------===// - -#include "__config" -#ifndef _LIBCPP_HAS_NO_THREADS - -#include "thread" -#include "exception" -#include "vector" -#include "future" -#include "limits" - -#if __has_include(<unistd.h>) -# include <unistd.h> // for sysconf -#endif - -#if defined(__NetBSD__) -#pragma weak pthread_create // Do not create libpthread dependency -#endif - -#if defined(_LIBCPP_WIN32API) -#include <windows.h> -#endif - -#if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB) -#pragma comment(lib, "pthread") -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -thread::~thread() -{ - if (!__libcpp_thread_isnull(&__t_)) - terminate(); -} - -void -thread::join() -{ - int ec = EINVAL; - if (!__libcpp_thread_isnull(&__t_)) - { - ec = __libcpp_thread_join(&__t_); - if (ec == 0) - __t_ = _LIBCPP_NULL_THREAD; - } - - if (ec) - __throw_system_error(ec, "thread::join failed"); -} - -void -thread::detach() -{ - int ec = EINVAL; - if (!__libcpp_thread_isnull(&__t_)) - { - ec = __libcpp_thread_detach(&__t_); - if (ec == 0) - __t_ = _LIBCPP_NULL_THREAD; - } - - if (ec) - __throw_system_error(ec, "thread::detach failed"); -} - -unsigned -thread::hardware_concurrency() noexcept -{ -#if defined(_SC_NPROCESSORS_ONLN) - long result = sysconf(_SC_NPROCESSORS_ONLN); - // sysconf returns -1 if the name is invalid, the option does not exist or - // does not have a definite limit. - // if sysconf returns some other negative number, we have no idea - // what is going on. Default to something safe. - if (result < 0) - return 0; - return static_cast<unsigned>(result); -#elif defined(_LIBCPP_WIN32API) - SYSTEM_INFO info; - GetSystemInfo(&info); - return info.dwNumberOfProcessors; -#else // defined(CTL_HW) && defined(HW_NCPU) - // TODO: grovel through /proc or check cpuid on x86 and similar - // instructions on other architectures. -# if defined(_LIBCPP_WARNING) - _LIBCPP_WARNING("hardware_concurrency not yet implemented") -# else -# warning hardware_concurrency not yet implemented -# endif - return 0; // Means not computable [thread.thread.static] -#endif // defined(CTL_HW) && defined(HW_NCPU) -} - -namespace this_thread -{ - -void -sleep_for(const chrono::nanoseconds& ns) -{ - if (ns > chrono::nanoseconds::zero()) - { - __libcpp_thread_sleep_for(ns); - } -} - -} // this_thread - -__thread_specific_ptr<__thread_struct>& -__thread_local_data() -{ - static __thread_specific_ptr<__thread_struct> __p; - return __p; -} - -// __thread_struct_imp - -template <class T> -class _LIBCPP_HIDDEN __hidden_allocator -{ -public: - typedef T value_type; - - T* allocate(size_t __n) - {return static_cast<T*>(::operator new(__n * sizeof(T)));} - void deallocate(T* __p, size_t) {::operator delete(static_cast<void*>(__p));} - - size_t max_size() const {return size_t(~0) / sizeof(T);} -}; - -class _LIBCPP_HIDDEN __thread_struct_imp -{ - typedef vector<__assoc_sub_state*, - __hidden_allocator<__assoc_sub_state*> > _AsyncStates; - typedef vector<pair<condition_variable*, mutex*>, - __hidden_allocator<pair<condition_variable*, mutex*> > > _Notify; - - _AsyncStates async_states_; - _Notify notify_; - - __thread_struct_imp(const __thread_struct_imp&); - __thread_struct_imp& operator=(const __thread_struct_imp&); -public: - __thread_struct_imp() {} - ~__thread_struct_imp(); - - void notify_all_at_thread_exit(condition_variable* cv, mutex* m); - void __make_ready_at_thread_exit(__assoc_sub_state* __s); -}; - -__thread_struct_imp::~__thread_struct_imp() -{ - for (_Notify::iterator i = notify_.begin(), e = notify_.end(); - i != e; ++i) - { - i->second->unlock(); - i->first->notify_all(); - } - for (_AsyncStates::iterator i = async_states_.begin(), e = async_states_.end(); - i != e; ++i) - { - (*i)->__make_ready(); - (*i)->__release_shared(); - } -} - -void -__thread_struct_imp::notify_all_at_thread_exit(condition_variable* cv, mutex* m) -{ - notify_.push_back(pair<condition_variable*, mutex*>(cv, m)); -} - -void -__thread_struct_imp::__make_ready_at_thread_exit(__assoc_sub_state* __s) -{ - async_states_.push_back(__s); - __s->__add_shared(); -} - -// __thread_struct - -__thread_struct::__thread_struct() - : __p_(new __thread_struct_imp) -{ -} - -__thread_struct::~__thread_struct() -{ - delete __p_; -} - -void -__thread_struct::notify_all_at_thread_exit(condition_variable* cv, mutex* m) -{ - __p_->notify_all_at_thread_exit(cv, m); -} - -void -__thread_struct::__make_ready_at_thread_exit(__assoc_sub_state* __s) -{ - __p_->__make_ready_at_thread_exit(__s); -} - -_LIBCPP_END_NAMESPACE_STD - -#endif // !_LIBCPP_HAS_NO_THREADS +// +//===----------------------------------------------------------------------===// + +#include "__config" +#ifndef _LIBCPP_HAS_NO_THREADS + +#include "thread" +#include "exception" +#include "vector" +#include "future" +#include "limits" + +#if __has_include(<unistd.h>) +# include <unistd.h> // for sysconf +#endif + +#if defined(__NetBSD__) +#pragma weak pthread_create // Do not create libpthread dependency +#endif + +#if defined(_LIBCPP_WIN32API) +#include <windows.h> +#endif + +#if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB) +#pragma comment(lib, "pthread") +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +thread::~thread() +{ + if (!__libcpp_thread_isnull(&__t_)) + terminate(); +} + +void +thread::join() +{ + int ec = EINVAL; + if (!__libcpp_thread_isnull(&__t_)) + { + ec = __libcpp_thread_join(&__t_); + if (ec == 0) + __t_ = _LIBCPP_NULL_THREAD; + } + + if (ec) + __throw_system_error(ec, "thread::join failed"); +} + +void +thread::detach() +{ + int ec = EINVAL; + if (!__libcpp_thread_isnull(&__t_)) + { + ec = __libcpp_thread_detach(&__t_); + if (ec == 0) + __t_ = _LIBCPP_NULL_THREAD; + } + + if (ec) + __throw_system_error(ec, "thread::detach failed"); +} + +unsigned +thread::hardware_concurrency() noexcept +{ +#if defined(_SC_NPROCESSORS_ONLN) + long result = sysconf(_SC_NPROCESSORS_ONLN); + // sysconf returns -1 if the name is invalid, the option does not exist or + // does not have a definite limit. + // if sysconf returns some other negative number, we have no idea + // what is going on. Default to something safe. + if (result < 0) + return 0; + return static_cast<unsigned>(result); +#elif defined(_LIBCPP_WIN32API) + SYSTEM_INFO info; + GetSystemInfo(&info); + return info.dwNumberOfProcessors; +#else // defined(CTL_HW) && defined(HW_NCPU) + // TODO: grovel through /proc or check cpuid on x86 and similar + // instructions on other architectures. +# if defined(_LIBCPP_WARNING) + _LIBCPP_WARNING("hardware_concurrency not yet implemented") +# else +# warning hardware_concurrency not yet implemented +# endif + return 0; // Means not computable [thread.thread.static] +#endif // defined(CTL_HW) && defined(HW_NCPU) +} + +namespace this_thread +{ + +void +sleep_for(const chrono::nanoseconds& ns) +{ + if (ns > chrono::nanoseconds::zero()) + { + __libcpp_thread_sleep_for(ns); + } +} + +} // this_thread + +__thread_specific_ptr<__thread_struct>& +__thread_local_data() +{ + static __thread_specific_ptr<__thread_struct> __p; + return __p; +} + +// __thread_struct_imp + +template <class T> +class _LIBCPP_HIDDEN __hidden_allocator +{ +public: + typedef T value_type; + + T* allocate(size_t __n) + {return static_cast<T*>(::operator new(__n * sizeof(T)));} + void deallocate(T* __p, size_t) {::operator delete(static_cast<void*>(__p));} + + size_t max_size() const {return size_t(~0) / sizeof(T);} +}; + +class _LIBCPP_HIDDEN __thread_struct_imp +{ + typedef vector<__assoc_sub_state*, + __hidden_allocator<__assoc_sub_state*> > _AsyncStates; + typedef vector<pair<condition_variable*, mutex*>, + __hidden_allocator<pair<condition_variable*, mutex*> > > _Notify; + + _AsyncStates async_states_; + _Notify notify_; + + __thread_struct_imp(const __thread_struct_imp&); + __thread_struct_imp& operator=(const __thread_struct_imp&); +public: + __thread_struct_imp() {} + ~__thread_struct_imp(); + + void notify_all_at_thread_exit(condition_variable* cv, mutex* m); + void __make_ready_at_thread_exit(__assoc_sub_state* __s); +}; + +__thread_struct_imp::~__thread_struct_imp() +{ + for (_Notify::iterator i = notify_.begin(), e = notify_.end(); + i != e; ++i) + { + i->second->unlock(); + i->first->notify_all(); + } + for (_AsyncStates::iterator i = async_states_.begin(), e = async_states_.end(); + i != e; ++i) + { + (*i)->__make_ready(); + (*i)->__release_shared(); + } +} + +void +__thread_struct_imp::notify_all_at_thread_exit(condition_variable* cv, mutex* m) +{ + notify_.push_back(pair<condition_variable*, mutex*>(cv, m)); +} + +void +__thread_struct_imp::__make_ready_at_thread_exit(__assoc_sub_state* __s) +{ + async_states_.push_back(__s); + __s->__add_shared(); +} + +// __thread_struct + +__thread_struct::__thread_struct() + : __p_(new __thread_struct_imp) +{ +} + +__thread_struct::~__thread_struct() +{ + delete __p_; +} + +void +__thread_struct::notify_all_at_thread_exit(condition_variable* cv, mutex* m) +{ + __p_->notify_all_at_thread_exit(cv, m); +} + +void +__thread_struct::__make_ready_at_thread_exit(__assoc_sub_state* __s) +{ + __p_->__make_ready_at_thread_exit(__s); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // !_LIBCPP_HAS_NO_THREADS |