146035553Spatrick// -*- C++ -*- 2*4bdff4beSrobert//===----------------------------------------------------------------------===// 346035553Spatrick// 446035553Spatrick// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 546035553Spatrick// See https://llvm.org/LICENSE.txt for license information. 646035553Spatrick// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 746035553Spatrick// 846035553Spatrick//===----------------------------------------------------------------------===// 946035553Spatrick 1046035553Spatrick#ifndef _LIBCPP_THREAD 1146035553Spatrick#define _LIBCPP_THREAD 1246035553Spatrick 1346035553Spatrick/* 1446035553Spatrick 1546035553Spatrick thread synopsis 1646035553Spatrick 1746035553Spatricknamespace std 1846035553Spatrick{ 1946035553Spatrick 2046035553Spatrickclass thread 2146035553Spatrick{ 2246035553Spatrickpublic: 2346035553Spatrick class id; 2446035553Spatrick typedef pthread_t native_handle_type; 2546035553Spatrick 2646035553Spatrick thread() noexcept; 2746035553Spatrick template <class F, class ...Args> explicit thread(F&& f, Args&&... args); 2846035553Spatrick ~thread(); 2946035553Spatrick 3046035553Spatrick thread(const thread&) = delete; 3146035553Spatrick thread(thread&& t) noexcept; 3246035553Spatrick 3346035553Spatrick thread& operator=(const thread&) = delete; 3446035553Spatrick thread& operator=(thread&& t) noexcept; 3546035553Spatrick 3646035553Spatrick void swap(thread& t) noexcept; 3746035553Spatrick 3846035553Spatrick bool joinable() const noexcept; 3946035553Spatrick void join(); 4046035553Spatrick void detach(); 4146035553Spatrick id get_id() const noexcept; 4246035553Spatrick native_handle_type native_handle(); 4346035553Spatrick 4446035553Spatrick static unsigned hardware_concurrency() noexcept; 4546035553Spatrick}; 4646035553Spatrick 4746035553Spatrickvoid swap(thread& x, thread& y) noexcept; 4846035553Spatrick 4946035553Spatrickclass thread::id 5046035553Spatrick{ 5146035553Spatrickpublic: 5246035553Spatrick id() noexcept; 5346035553Spatrick}; 5446035553Spatrick 5546035553Spatrickbool operator==(thread::id x, thread::id y) noexcept; 56*4bdff4beSrobertbool operator!=(thread::id x, thread::id y) noexcept; // removed in C++20 57*4bdff4beSrobertbool operator< (thread::id x, thread::id y) noexcept; // removed in C++20 58*4bdff4beSrobertbool operator<=(thread::id x, thread::id y) noexcept; // removed in C++20 59*4bdff4beSrobertbool operator> (thread::id x, thread::id y) noexcept; // removed in C++20 60*4bdff4beSrobertbool operator>=(thread::id x, thread::id y) noexcept; // removed in C++20 61*4bdff4beSrobertstrong_ordering operator<=>(thread::id x, thread::id y) noexcept; // C++20 6246035553Spatrick 6346035553Spatricktemplate<class charT, class traits> 6446035553Spatrickbasic_ostream<charT, traits>& 6546035553Spatrickoperator<<(basic_ostream<charT, traits>& out, thread::id id); 6646035553Spatrick 6746035553Spatricknamespace this_thread 6846035553Spatrick{ 6946035553Spatrick 7046035553Spatrickthread::id get_id() noexcept; 7146035553Spatrick 7246035553Spatrickvoid yield() noexcept; 7346035553Spatrick 7446035553Spatricktemplate <class Clock, class Duration> 7546035553Spatrickvoid sleep_until(const chrono::time_point<Clock, Duration>& abs_time); 7646035553Spatrick 7746035553Spatricktemplate <class Rep, class Period> 7846035553Spatrickvoid sleep_for(const chrono::duration<Rep, Period>& rel_time); 7946035553Spatrick 8046035553Spatrick} // this_thread 8146035553Spatrick 8246035553Spatrick} // std 8346035553Spatrick 8446035553Spatrick*/ 8546035553Spatrick 86*4bdff4beSrobert#include <__assert> // all public C++ headers provide the assertion handler 8746035553Spatrick#include <__config> 88*4bdff4beSrobert#include <__functional/hash.h> 89*4bdff4beSrobert#include <__memory/unique_ptr.h> 9076d0caaeSpatrick#include <__mutex_base> 91*4bdff4beSrobert#include <__thread/poll_with_backoff.h> 92*4bdff4beSrobert#include <__thread/timed_backoff_policy.h> 9376d0caaeSpatrick#include <__threading_support> 9476d0caaeSpatrick#include <__utility/forward.h> 9546035553Spatrick#include <cstddef> 9676d0caaeSpatrick#include <iosfwd> 9746035553Spatrick#include <system_error> 9846035553Spatrick#include <tuple> 9976d0caaeSpatrick#include <type_traits> 100*4bdff4beSrobert#include <version> 101*4bdff4beSrobert 102*4bdff4beSrobert// standard-mandated includes 103*4bdff4beSrobert 104*4bdff4beSrobert// [thread.syn] 105*4bdff4beSrobert#include <compare> 10646035553Spatrick 10746035553Spatrick#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 10846035553Spatrick# pragma GCC system_header 10946035553Spatrick#endif 11046035553Spatrick 11146035553Spatrick_LIBCPP_PUSH_MACROS 11246035553Spatrick#include <__undef_macros> 11346035553Spatrick 11446035553Spatrick#ifdef _LIBCPP_HAS_NO_THREADS 115*4bdff4beSrobert# error "<thread> is not supported since libc++ has been configured without support for threads." 116*4bdff4beSrobert#endif 11746035553Spatrick 11846035553Spatrick_LIBCPP_BEGIN_NAMESPACE_STD 11946035553Spatrick 12046035553Spatricktemplate <class _Tp> class __thread_specific_ptr; 12146035553Spatrickclass _LIBCPP_TYPE_VIS __thread_struct; 12246035553Spatrickclass _LIBCPP_HIDDEN __thread_struct_imp; 12346035553Spatrickclass __assoc_sub_state; 12446035553Spatrick 12546035553Spatrick_LIBCPP_FUNC_VIS __thread_specific_ptr<__thread_struct>& __thread_local_data(); 12646035553Spatrick 12746035553Spatrickclass _LIBCPP_TYPE_VIS __thread_struct 12846035553Spatrick{ 12946035553Spatrick __thread_struct_imp* __p_; 13046035553Spatrick 13146035553Spatrick __thread_struct(const __thread_struct&); 13246035553Spatrick __thread_struct& operator=(const __thread_struct&); 13346035553Spatrickpublic: 13446035553Spatrick __thread_struct(); 13546035553Spatrick ~__thread_struct(); 13646035553Spatrick 13746035553Spatrick void notify_all_at_thread_exit(condition_variable*, mutex*); 13846035553Spatrick void __make_ready_at_thread_exit(__assoc_sub_state*); 13946035553Spatrick}; 14046035553Spatrick 14146035553Spatricktemplate <class _Tp> 14246035553Spatrickclass __thread_specific_ptr 14346035553Spatrick{ 14446035553Spatrick __libcpp_tls_key __key_; 14546035553Spatrick 14646035553Spatrick // Only __thread_local_data() may construct a __thread_specific_ptr 14746035553Spatrick // and only with _Tp == __thread_struct. 14846035553Spatrick static_assert((is_same<_Tp, __thread_struct>::value), ""); 14946035553Spatrick __thread_specific_ptr(); 15046035553Spatrick friend _LIBCPP_FUNC_VIS __thread_specific_ptr<__thread_struct>& __thread_local_data(); 15146035553Spatrick 15246035553Spatrick __thread_specific_ptr(const __thread_specific_ptr&); 15346035553Spatrick __thread_specific_ptr& operator=(const __thread_specific_ptr&); 15446035553Spatrick 15546035553Spatrick _LIBCPP_HIDDEN static void _LIBCPP_TLS_DESTRUCTOR_CC __at_thread_exit(void*); 15646035553Spatrick 15746035553Spatrickpublic: 15846035553Spatrick typedef _Tp* pointer; 15946035553Spatrick 16046035553Spatrick ~__thread_specific_ptr(); 16146035553Spatrick 16246035553Spatrick _LIBCPP_INLINE_VISIBILITY 16346035553Spatrick pointer get() const {return static_cast<_Tp*>(__libcpp_tls_get(__key_));} 16446035553Spatrick _LIBCPP_INLINE_VISIBILITY 16546035553Spatrick pointer operator*() const {return *get();} 16646035553Spatrick _LIBCPP_INLINE_VISIBILITY 16746035553Spatrick pointer operator->() const {return get();} 16846035553Spatrick void set_pointer(pointer __p); 16946035553Spatrick}; 17046035553Spatrick 17146035553Spatricktemplate <class _Tp> 17246035553Spatrickvoid _LIBCPP_TLS_DESTRUCTOR_CC 17346035553Spatrick__thread_specific_ptr<_Tp>::__at_thread_exit(void* __p) 17446035553Spatrick{ 17546035553Spatrick delete static_cast<pointer>(__p); 17646035553Spatrick} 17746035553Spatrick 17846035553Spatricktemplate <class _Tp> 17946035553Spatrick__thread_specific_ptr<_Tp>::__thread_specific_ptr() 18046035553Spatrick{ 18146035553Spatrick int __ec = 18246035553Spatrick __libcpp_tls_create(&__key_, &__thread_specific_ptr::__at_thread_exit); 18346035553Spatrick if (__ec) 18446035553Spatrick __throw_system_error(__ec, "__thread_specific_ptr construction failed"); 18546035553Spatrick} 18646035553Spatrick 18746035553Spatricktemplate <class _Tp> 18846035553Spatrick__thread_specific_ptr<_Tp>::~__thread_specific_ptr() 18946035553Spatrick{ 19046035553Spatrick // __thread_specific_ptr is only created with a static storage duration 19146035553Spatrick // so this destructor is only invoked during program termination. Invoking 19246035553Spatrick // pthread_key_delete(__key_) may prevent other threads from deleting their 19346035553Spatrick // thread local data. For this reason we leak the key. 19446035553Spatrick} 19546035553Spatrick 19646035553Spatricktemplate <class _Tp> 19746035553Spatrickvoid 19846035553Spatrick__thread_specific_ptr<_Tp>::set_pointer(pointer __p) 19946035553Spatrick{ 20046035553Spatrick _LIBCPP_ASSERT(get() == nullptr, 20146035553Spatrick "Attempting to overwrite thread local data"); 202*4bdff4beSrobert std::__libcpp_tls_set(__key_, __p); 20346035553Spatrick} 20446035553Spatrick 20546035553Spatricktemplate<> 20646035553Spatrickstruct _LIBCPP_TEMPLATE_VIS hash<__thread_id> 207*4bdff4beSrobert : public __unary_function<__thread_id, size_t> 20846035553Spatrick{ 20946035553Spatrick _LIBCPP_INLINE_VISIBILITY 21046035553Spatrick size_t operator()(__thread_id __v) const _NOEXCEPT 21146035553Spatrick { 21246035553Spatrick return hash<__libcpp_thread_id>()(__v.__id_); 21346035553Spatrick } 21446035553Spatrick}; 21546035553Spatrick 21646035553Spatricktemplate<class _CharT, class _Traits> 21746035553Spatrick_LIBCPP_INLINE_VISIBILITY 21846035553Spatrickbasic_ostream<_CharT, _Traits>& 21946035553Spatrickoperator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id) 22046035553Spatrick{return __os << __id.__id_;} 22146035553Spatrick 22246035553Spatrickclass _LIBCPP_TYPE_VIS thread 22346035553Spatrick{ 22446035553Spatrick __libcpp_thread_t __t_; 22546035553Spatrick 22646035553Spatrick thread(const thread&); 22746035553Spatrick thread& operator=(const thread&); 22846035553Spatrickpublic: 22946035553Spatrick typedef __thread_id id; 23046035553Spatrick typedef __libcpp_thread_t native_handle_type; 23146035553Spatrick 23246035553Spatrick _LIBCPP_INLINE_VISIBILITY 23346035553Spatrick thread() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) {} 23446035553Spatrick#ifndef _LIBCPP_CXX03_LANG 23546035553Spatrick template <class _Fp, class ..._Args, 236*4bdff4beSrobert class = __enable_if_t<!is_same<__remove_cvref_t<_Fp>, thread>::value> > 23746035553Spatrick _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS 23846035553Spatrick explicit thread(_Fp&& __f, _Args&&... __args); 23946035553Spatrick#else // _LIBCPP_CXX03_LANG 24046035553Spatrick template <class _Fp> 24146035553Spatrick _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS 24246035553Spatrick explicit thread(_Fp __f); 24346035553Spatrick#endif 24446035553Spatrick ~thread(); 24546035553Spatrick 24646035553Spatrick _LIBCPP_INLINE_VISIBILITY 247037e7968Spatrick thread(thread&& __t) _NOEXCEPT : __t_(__t.__t_) { 248037e7968Spatrick __t.__t_ = _LIBCPP_NULL_THREAD; 249037e7968Spatrick } 250037e7968Spatrick 25146035553Spatrick _LIBCPP_INLINE_VISIBILITY 252037e7968Spatrick thread& operator=(thread&& __t) _NOEXCEPT { 253037e7968Spatrick if (!__libcpp_thread_isnull(&__t_)) 254037e7968Spatrick terminate(); 255037e7968Spatrick __t_ = __t.__t_; 256037e7968Spatrick __t.__t_ = _LIBCPP_NULL_THREAD; 257037e7968Spatrick return *this; 258037e7968Spatrick } 25946035553Spatrick 26046035553Spatrick _LIBCPP_INLINE_VISIBILITY 26146035553Spatrick void swap(thread& __t) _NOEXCEPT {_VSTD::swap(__t_, __t.__t_);} 26246035553Spatrick 26346035553Spatrick _LIBCPP_INLINE_VISIBILITY 26446035553Spatrick bool joinable() const _NOEXCEPT {return !__libcpp_thread_isnull(&__t_);} 26546035553Spatrick void join(); 26646035553Spatrick void detach(); 26746035553Spatrick _LIBCPP_INLINE_VISIBILITY 26846035553Spatrick id get_id() const _NOEXCEPT {return __libcpp_thread_get_id(&__t_);} 26946035553Spatrick _LIBCPP_INLINE_VISIBILITY 27046035553Spatrick native_handle_type native_handle() _NOEXCEPT {return __t_;} 27146035553Spatrick 27246035553Spatrick static unsigned hardware_concurrency() _NOEXCEPT; 27346035553Spatrick}; 27446035553Spatrick 27546035553Spatrick#ifndef _LIBCPP_CXX03_LANG 27646035553Spatrick 27746035553Spatricktemplate <class _TSp, class _Fp, class ..._Args, size_t ..._Indices> 27846035553Spatrickinline _LIBCPP_INLINE_VISIBILITY 27946035553Spatrickvoid 28046035553Spatrick__thread_execute(tuple<_TSp, _Fp, _Args...>& __t, __tuple_indices<_Indices...>) 28146035553Spatrick{ 28276d0caaeSpatrick _VSTD::__invoke(_VSTD::move(_VSTD::get<1>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...); 28346035553Spatrick} 28446035553Spatrick 28546035553Spatricktemplate <class _Fp> 28646035553Spatrick_LIBCPP_INLINE_VISIBILITY 28746035553Spatrickvoid* __thread_proxy(void* __vp) 28846035553Spatrick{ 28976d0caaeSpatrick // _Fp = tuple< unique_ptr<__thread_struct>, Functor, Args...> 29076d0caaeSpatrick unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp)); 29176d0caaeSpatrick __thread_local_data().set_pointer(_VSTD::get<0>(*__p.get()).release()); 29246035553Spatrick typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 2>::type _Index; 29376d0caaeSpatrick _VSTD::__thread_execute(*__p.get(), _Index()); 29446035553Spatrick return nullptr; 29546035553Spatrick} 29646035553Spatrick 29746035553Spatricktemplate <class _Fp, class ..._Args, 29846035553Spatrick class 29946035553Spatrick > 30046035553Spatrickthread::thread(_Fp&& __f, _Args&&... __args) 30146035553Spatrick{ 30246035553Spatrick typedef unique_ptr<__thread_struct> _TSPtr; 30346035553Spatrick _TSPtr __tsp(new __thread_struct); 30446035553Spatrick typedef tuple<_TSPtr, typename decay<_Fp>::type, typename decay<_Args>::type...> _Gp; 30576d0caaeSpatrick unique_ptr<_Gp> __p( 30676d0caaeSpatrick new _Gp(_VSTD::move(__tsp), 307*4bdff4beSrobert _VSTD::forward<_Fp>(__f), 308*4bdff4beSrobert _VSTD::forward<_Args>(__args)...)); 30976d0caaeSpatrick int __ec = _VSTD::__libcpp_thread_create(&__t_, &__thread_proxy<_Gp>, __p.get()); 31046035553Spatrick if (__ec == 0) 31146035553Spatrick __p.release(); 31246035553Spatrick else 31346035553Spatrick __throw_system_error(__ec, "thread constructor failed"); 31446035553Spatrick} 31546035553Spatrick 31646035553Spatrick#else // _LIBCPP_CXX03_LANG 31746035553Spatrick 31846035553Spatricktemplate <class _Fp> 31946035553Spatrickstruct __thread_invoke_pair { 32046035553Spatrick // This type is used to pass memory for thread local storage and a functor 32146035553Spatrick // to a newly created thread because std::pair doesn't work with 32246035553Spatrick // std::unique_ptr in C++03. 32346035553Spatrick __thread_invoke_pair(_Fp& __f) : __tsp_(new __thread_struct), __fn_(__f) {} 32446035553Spatrick unique_ptr<__thread_struct> __tsp_; 32546035553Spatrick _Fp __fn_; 32646035553Spatrick}; 32746035553Spatrick 32846035553Spatricktemplate <class _Fp> 329*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI void* __thread_proxy_cxx03(void* __vp) 33046035553Spatrick{ 33176d0caaeSpatrick unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp)); 33246035553Spatrick __thread_local_data().set_pointer(__p->__tsp_.release()); 33346035553Spatrick (__p->__fn_)(); 33446035553Spatrick return nullptr; 33546035553Spatrick} 33646035553Spatrick 33746035553Spatricktemplate <class _Fp> 33846035553Spatrickthread::thread(_Fp __f) 33946035553Spatrick{ 34046035553Spatrick 34146035553Spatrick typedef __thread_invoke_pair<_Fp> _InvokePair; 34276d0caaeSpatrick typedef unique_ptr<_InvokePair> _PairPtr; 34346035553Spatrick _PairPtr __pp(new _InvokePair(__f)); 34476d0caaeSpatrick int __ec = _VSTD::__libcpp_thread_create(&__t_, &__thread_proxy_cxx03<_InvokePair>, __pp.get()); 34546035553Spatrick if (__ec == 0) 34646035553Spatrick __pp.release(); 34746035553Spatrick else 34846035553Spatrick __throw_system_error(__ec, "thread constructor failed"); 34946035553Spatrick} 35046035553Spatrick 35146035553Spatrick#endif // _LIBCPP_CXX03_LANG 35246035553Spatrick 35346035553Spatrickinline _LIBCPP_INLINE_VISIBILITY 35446035553Spatrickvoid swap(thread& __x, thread& __y) _NOEXCEPT {__x.swap(__y);} 35546035553Spatrick 35646035553Spatricknamespace this_thread 35746035553Spatrick{ 35846035553Spatrick 35946035553Spatrick_LIBCPP_FUNC_VIS void sleep_for(const chrono::nanoseconds& __ns); 36046035553Spatrick 36146035553Spatricktemplate <class _Rep, class _Period> 362*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI void 36346035553Spatricksleep_for(const chrono::duration<_Rep, _Period>& __d) 36446035553Spatrick{ 36576d0caaeSpatrick if (__d > chrono::duration<_Rep, _Period>::zero()) 36646035553Spatrick { 36776d0caaeSpatrick // The standard guarantees a 64bit signed integer resolution for nanoseconds, 36876d0caaeSpatrick // so use INT64_MAX / 1e9 as cut-off point. Use a constant to avoid <climits> 36976d0caaeSpatrick // and issues with long double folding on PowerPC with GCC. 37076d0caaeSpatrick _LIBCPP_CONSTEXPR chrono::duration<long double> _Max = 37176d0caaeSpatrick chrono::duration<long double>(9223372036.0L); 37276d0caaeSpatrick chrono::nanoseconds __ns; 37346035553Spatrick if (__d < _Max) 37446035553Spatrick { 37576d0caaeSpatrick __ns = chrono::duration_cast<chrono::nanoseconds>(__d); 37646035553Spatrick if (__ns < __d) 37746035553Spatrick ++__ns; 37846035553Spatrick } 37946035553Spatrick else 38076d0caaeSpatrick __ns = chrono::nanoseconds::max(); 38176d0caaeSpatrick this_thread::sleep_for(__ns); 38246035553Spatrick } 38346035553Spatrick} 38446035553Spatrick 38546035553Spatricktemplate <class _Clock, class _Duration> 386*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI void 38746035553Spatricksleep_until(const chrono::time_point<_Clock, _Duration>& __t) 38846035553Spatrick{ 38946035553Spatrick mutex __mut; 39046035553Spatrick condition_variable __cv; 39146035553Spatrick unique_lock<mutex> __lk(__mut); 39246035553Spatrick while (_Clock::now() < __t) 39346035553Spatrick __cv.wait_until(__lk, __t); 39446035553Spatrick} 39546035553Spatrick 39646035553Spatricktemplate <class _Duration> 39746035553Spatrickinline _LIBCPP_INLINE_VISIBILITY 39846035553Spatrickvoid 39946035553Spatricksleep_until(const chrono::time_point<chrono::steady_clock, _Duration>& __t) 40046035553Spatrick{ 40176d0caaeSpatrick this_thread::sleep_for(__t - chrono::steady_clock::now()); 40246035553Spatrick} 40346035553Spatrick 40446035553Spatrickinline _LIBCPP_INLINE_VISIBILITY 40546035553Spatrickvoid yield() _NOEXCEPT {__libcpp_thread_yield();} 40646035553Spatrick 407*4bdff4beSrobert} // namespace this_thread 40846035553Spatrick 40946035553Spatrick_LIBCPP_END_NAMESPACE_STD 41046035553Spatrick 41146035553Spatrick_LIBCPP_POP_MACROS 41246035553Spatrick 413*4bdff4beSrobert#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 17 414*4bdff4beSrobert# include <chrono> 415*4bdff4beSrobert#endif 416*4bdff4beSrobert 417*4bdff4beSrobert#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 418*4bdff4beSrobert# include <functional> 419*4bdff4beSrobert#endif 420*4bdff4beSrobert 42146035553Spatrick#endif // _LIBCPP_THREAD 422