1// -*- C++ -*- 2//===----------------------------------------------------------------------===// 3// 4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5// See https://llvm.org/LICENSE.txt for license information. 6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7// 8//===----------------------------------------------------------------------===// 9 10#ifndef _LIBCPP_THREAD 11#define _LIBCPP_THREAD 12 13/* 14 15 thread synopsis 16 17namespace std 18{ 19 20class thread 21{ 22public: 23 class id; 24 typedef pthread_t native_handle_type; 25 26 thread() noexcept; 27 template <class F, class ...Args> explicit thread(F&& f, Args&&... args); 28 ~thread(); 29 30 thread(const thread&) = delete; 31 thread(thread&& t) noexcept; 32 33 thread& operator=(const thread&) = delete; 34 thread& operator=(thread&& t) noexcept; 35 36 void swap(thread& t) noexcept; 37 38 bool joinable() const noexcept; 39 void join(); 40 void detach(); 41 id get_id() const noexcept; 42 native_handle_type native_handle(); 43 44 static unsigned hardware_concurrency() noexcept; 45}; 46 47void swap(thread& x, thread& y) noexcept; 48 49class thread::id 50{ 51public: 52 id() noexcept; 53}; 54 55bool operator==(thread::id x, thread::id y) noexcept; 56bool operator!=(thread::id x, thread::id y) noexcept; // removed in C++20 57bool operator< (thread::id x, thread::id y) noexcept; // removed in C++20 58bool operator<=(thread::id x, thread::id y) noexcept; // removed in C++20 59bool operator> (thread::id x, thread::id y) noexcept; // removed in C++20 60bool operator>=(thread::id x, thread::id y) noexcept; // removed in C++20 61strong_ordering operator<=>(thread::id x, thread::id y) noexcept; // C++20 62 63template<class charT, class traits> 64basic_ostream<charT, traits>& 65operator<<(basic_ostream<charT, traits>& out, thread::id id); 66 67template<class charT> 68struct formatter<thread::id, charT>; 69 70namespace this_thread 71{ 72 73thread::id get_id() noexcept; 74 75void yield() noexcept; 76 77template <class Clock, class Duration> 78void sleep_until(const chrono::time_point<Clock, Duration>& abs_time); 79 80template <class Rep, class Period> 81void sleep_for(const chrono::duration<Rep, Period>& rel_time); 82 83} // this_thread 84 85} // std 86 87*/ 88 89#include <__assert> // all public C++ headers provide the assertion handler 90#include <__availability> 91#include <__chrono/steady_clock.h> 92#include <__chrono/time_point.h> 93#include <__concepts/arithmetic.h> 94#include <__condition_variable/condition_variable.h> 95#include <__config> 96#include <__exception/terminate.h> 97#include <__format/concepts.h> 98#include <__format/format_parse_context.h> 99#include <__format/formatter.h> 100#include <__format/formatter_integral.h> 101#include <__format/parser_std_format_spec.h> 102#include <__functional/hash.h> 103#include <__functional/unary_function.h> 104#include <__memory/addressof.h> 105#include <__memory/unique_ptr.h> 106#include <__mutex/mutex.h> 107#include <__mutex/unique_lock.h> 108#include <__system_error/system_error.h> 109#include <__thread/poll_with_backoff.h> 110#include <__thread/timed_backoff_policy.h> 111#include <__threading_support> 112#include <__utility/forward.h> 113#include <cstddef> 114#include <cstdint> 115#include <iosfwd> 116#include <tuple> 117#include <version> 118 119// standard-mandated includes 120 121// [thread.syn] 122#include <compare> 123 124#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 125# pragma GCC system_header 126#endif 127 128_LIBCPP_PUSH_MACROS 129#include <__undef_macros> 130 131#ifdef _LIBCPP_HAS_NO_THREADS 132# error "<thread> is not supported since libc++ has been configured without support for threads." 133#endif 134 135_LIBCPP_BEGIN_NAMESPACE_STD 136 137template <class _Tp> class __thread_specific_ptr; 138class _LIBCPP_TYPE_VIS __thread_struct; 139class _LIBCPP_HIDDEN __thread_struct_imp; 140class __assoc_sub_state; 141 142_LIBCPP_FUNC_VIS __thread_specific_ptr<__thread_struct>& __thread_local_data(); 143 144class _LIBCPP_TYPE_VIS __thread_struct 145{ 146 __thread_struct_imp* __p_; 147 148 __thread_struct(const __thread_struct&); 149 __thread_struct& operator=(const __thread_struct&); 150public: 151 __thread_struct(); 152 ~__thread_struct(); 153 154 void notify_all_at_thread_exit(condition_variable*, mutex*); 155 void __make_ready_at_thread_exit(__assoc_sub_state*); 156}; 157 158template <class _Tp> 159class __thread_specific_ptr 160{ 161 __libcpp_tls_key __key_; 162 163 // Only __thread_local_data() may construct a __thread_specific_ptr 164 // and only with _Tp == __thread_struct. 165 static_assert((is_same<_Tp, __thread_struct>::value), ""); 166 __thread_specific_ptr(); 167 friend _LIBCPP_FUNC_VIS __thread_specific_ptr<__thread_struct>& __thread_local_data(); 168 169 __thread_specific_ptr(const __thread_specific_ptr&); 170 __thread_specific_ptr& operator=(const __thread_specific_ptr&); 171 172 _LIBCPP_HIDDEN static void _LIBCPP_TLS_DESTRUCTOR_CC __at_thread_exit(void*); 173 174public: 175 typedef _Tp* pointer; 176 177 ~__thread_specific_ptr(); 178 179 _LIBCPP_INLINE_VISIBILITY 180 pointer get() const {return static_cast<_Tp*>(__libcpp_tls_get(__key_));} 181 _LIBCPP_INLINE_VISIBILITY 182 pointer operator*() const {return *get();} 183 _LIBCPP_INLINE_VISIBILITY 184 pointer operator->() const {return get();} 185 void set_pointer(pointer __p); 186}; 187 188template <class _Tp> 189void _LIBCPP_TLS_DESTRUCTOR_CC 190__thread_specific_ptr<_Tp>::__at_thread_exit(void* __p) 191{ 192 delete static_cast<pointer>(__p); 193} 194 195template <class _Tp> 196__thread_specific_ptr<_Tp>::__thread_specific_ptr() 197{ 198 int __ec = 199 __libcpp_tls_create(&__key_, &__thread_specific_ptr::__at_thread_exit); 200 if (__ec) 201 __throw_system_error(__ec, "__thread_specific_ptr construction failed"); 202} 203 204template <class _Tp> 205__thread_specific_ptr<_Tp>::~__thread_specific_ptr() 206{ 207 // __thread_specific_ptr is only created with a static storage duration 208 // so this destructor is only invoked during program termination. Invoking 209 // pthread_key_delete(__key_) may prevent other threads from deleting their 210 // thread local data. For this reason we leak the key. 211} 212 213template <class _Tp> 214void 215__thread_specific_ptr<_Tp>::set_pointer(pointer __p) 216{ 217 _LIBCPP_ASSERT(get() == nullptr, 218 "Attempting to overwrite thread local data"); 219 std::__libcpp_tls_set(__key_, __p); 220} 221 222template<> 223struct _LIBCPP_TEMPLATE_VIS hash<__thread_id> 224 : public __unary_function<__thread_id, size_t> 225{ 226 _LIBCPP_INLINE_VISIBILITY 227 size_t operator()(__thread_id __v) const _NOEXCEPT 228 { 229 return hash<__libcpp_thread_id>()(__v.__id_); 230 } 231}; 232 233template<class _CharT, class _Traits> 234_LIBCPP_INLINE_VISIBILITY 235basic_ostream<_CharT, _Traits>& 236operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id) 237{return __os << __id.__id_;} 238 239#if _LIBCPP_STD_VER >= 23 240template <__fmt_char_type _CharT> 241struct _LIBCPP_TEMPLATE_VIS formatter<__thread_id, _CharT> { 242 public: 243 template <class _ParseContext> 244 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { 245 return __parser_.__parse(__ctx, __format_spec::__fields_fill_align_width); 246 } 247 248 template <class _FormatContext> 249 _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(__thread_id __id, _FormatContext& __ctx) const { 250 // In __threading_support __libcpp_thread_id is either a 251 // unsigned long long or a pthread_t. 252 // 253 // The type of pthread_t is left unspecified in POSIX so it can be any 254 // type. The most logical types are an integral or pointer. 255 // On Linux systems pthread_t is an unsigned long long. 256 // On Apple systems pthread_t is a pointer type. 257 // 258 // Note the output should match what the stream operator does. Since 259 // the ostream operator has been shipped years before this formatter 260 // was added to the Standard, this formatter does what the stream 261 // operator does. This may require platform specific changes. 262 263 using _Tp = decltype(__get_underlying_id(__id)); 264 using _Cp = conditional_t<integral<_Tp>, _Tp, conditional_t<is_pointer_v<_Tp>, uintptr_t, void>>; 265 static_assert(!is_same_v<_Cp, void>, "unsupported thread::id type, please file a bug report"); 266 267 __format_spec::__parsed_specifications<_CharT> __specs = __parser_.__get_parsed_std_specifications(__ctx); 268 if constexpr (is_pointer_v<_Tp>) { 269 __specs.__std_.__alternate_form_ = true; 270 __specs.__std_.__type_ = __format_spec::__type::__hexadecimal_lower_case; 271 } 272 return __formatter::__format_integer(reinterpret_cast<_Cp>(__get_underlying_id(__id)), __ctx, __specs); 273 } 274 275 __format_spec::__parser<_CharT> __parser_{.__alignment_ = __format_spec::__alignment::__right}; 276}; 277#endif // _LIBCPP_STD_VER >= 23 278 279class _LIBCPP_TYPE_VIS thread 280{ 281 __libcpp_thread_t __t_; 282 283 thread(const thread&); 284 thread& operator=(const thread&); 285public: 286 typedef __thread_id id; 287 typedef __libcpp_thread_t native_handle_type; 288 289 _LIBCPP_INLINE_VISIBILITY 290 thread() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) {} 291#ifndef _LIBCPP_CXX03_LANG 292 template <class _Fp, class ..._Args, 293 class = __enable_if_t<!is_same<__remove_cvref_t<_Fp>, thread>::value> > 294 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS 295 explicit thread(_Fp&& __f, _Args&&... __args); 296#else // _LIBCPP_CXX03_LANG 297 template <class _Fp> 298 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS 299 explicit thread(_Fp __f); 300#endif 301 ~thread(); 302 303 _LIBCPP_INLINE_VISIBILITY 304 thread(thread&& __t) _NOEXCEPT : __t_(__t.__t_) { 305 __t.__t_ = _LIBCPP_NULL_THREAD; 306 } 307 308 _LIBCPP_INLINE_VISIBILITY 309 thread& operator=(thread&& __t) _NOEXCEPT { 310 if (!__libcpp_thread_isnull(&__t_)) 311 terminate(); 312 __t_ = __t.__t_; 313 __t.__t_ = _LIBCPP_NULL_THREAD; 314 return *this; 315 } 316 317 _LIBCPP_INLINE_VISIBILITY 318 void swap(thread& __t) _NOEXCEPT {_VSTD::swap(__t_, __t.__t_);} 319 320 _LIBCPP_INLINE_VISIBILITY 321 bool joinable() const _NOEXCEPT {return !__libcpp_thread_isnull(&__t_);} 322 void join(); 323 void detach(); 324 _LIBCPP_INLINE_VISIBILITY 325 id get_id() const _NOEXCEPT {return __libcpp_thread_get_id(&__t_);} 326 _LIBCPP_INLINE_VISIBILITY 327 native_handle_type native_handle() _NOEXCEPT {return __t_;} 328 329 static unsigned hardware_concurrency() _NOEXCEPT; 330}; 331 332#ifndef _LIBCPP_CXX03_LANG 333 334template <class _TSp, class _Fp, class ..._Args, size_t ..._Indices> 335inline _LIBCPP_INLINE_VISIBILITY 336void 337__thread_execute(tuple<_TSp, _Fp, _Args...>& __t, __tuple_indices<_Indices...>) 338{ 339 _VSTD::__invoke(_VSTD::move(_VSTD::get<1>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...); 340} 341 342template <class _Fp> 343_LIBCPP_INLINE_VISIBILITY 344void* __thread_proxy(void* __vp) 345{ 346 // _Fp = tuple< unique_ptr<__thread_struct>, Functor, Args...> 347 unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp)); 348 __thread_local_data().set_pointer(_VSTD::get<0>(*__p.get()).release()); 349 typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 2>::type _Index; 350 _VSTD::__thread_execute(*__p.get(), _Index()); 351 return nullptr; 352} 353 354template <class _Fp, class ..._Args, 355 class 356 > 357thread::thread(_Fp&& __f, _Args&&... __args) 358{ 359 typedef unique_ptr<__thread_struct> _TSPtr; 360 _TSPtr __tsp(new __thread_struct); 361 typedef tuple<_TSPtr, __decay_t<_Fp>, __decay_t<_Args>...> _Gp; 362 unique_ptr<_Gp> __p( 363 new _Gp(_VSTD::move(__tsp), 364 _VSTD::forward<_Fp>(__f), 365 _VSTD::forward<_Args>(__args)...)); 366 int __ec = _VSTD::__libcpp_thread_create(&__t_, &__thread_proxy<_Gp>, __p.get()); 367 if (__ec == 0) 368 __p.release(); 369 else 370 __throw_system_error(__ec, "thread constructor failed"); 371} 372 373#else // _LIBCPP_CXX03_LANG 374 375template <class _Fp> 376struct __thread_invoke_pair { 377 // This type is used to pass memory for thread local storage and a functor 378 // to a newly created thread because std::pair doesn't work with 379 // std::unique_ptr in C++03. 380 _LIBCPP_HIDE_FROM_ABI __thread_invoke_pair(_Fp& __f) : __tsp_(new __thread_struct), __fn_(__f) {} 381 unique_ptr<__thread_struct> __tsp_; 382 _Fp __fn_; 383}; 384 385template <class _Fp> 386_LIBCPP_HIDE_FROM_ABI void* __thread_proxy_cxx03(void* __vp) 387{ 388 unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp)); 389 __thread_local_data().set_pointer(__p->__tsp_.release()); 390 (__p->__fn_)(); 391 return nullptr; 392} 393 394template <class _Fp> 395thread::thread(_Fp __f) 396{ 397 398 typedef __thread_invoke_pair<_Fp> _InvokePair; 399 typedef unique_ptr<_InvokePair> _PairPtr; 400 _PairPtr __pp(new _InvokePair(__f)); 401 int __ec = _VSTD::__libcpp_thread_create(&__t_, &__thread_proxy_cxx03<_InvokePair>, __pp.get()); 402 if (__ec == 0) 403 __pp.release(); 404 else 405 __throw_system_error(__ec, "thread constructor failed"); 406} 407 408#endif // _LIBCPP_CXX03_LANG 409 410inline _LIBCPP_INLINE_VISIBILITY 411void swap(thread& __x, thread& __y) _NOEXCEPT {__x.swap(__y);} 412 413namespace this_thread 414{ 415 416_LIBCPP_FUNC_VIS void sleep_for(const chrono::nanoseconds& __ns); 417 418template <class _Rep, class _Period> 419_LIBCPP_HIDE_FROM_ABI void 420sleep_for(const chrono::duration<_Rep, _Period>& __d) 421{ 422 if (__d > chrono::duration<_Rep, _Period>::zero()) 423 { 424 // The standard guarantees a 64bit signed integer resolution for nanoseconds, 425 // so use INT64_MAX / 1e9 as cut-off point. Use a constant to avoid <climits> 426 // and issues with long double folding on PowerPC with GCC. 427 _LIBCPP_CONSTEXPR chrono::duration<long double> __max = 428 chrono::duration<long double>(9223372036.0L); 429 chrono::nanoseconds __ns; 430 if (__d < __max) 431 { 432 __ns = chrono::duration_cast<chrono::nanoseconds>(__d); 433 if (__ns < __d) 434 ++__ns; 435 } 436 else 437 __ns = chrono::nanoseconds::max(); 438 this_thread::sleep_for(__ns); 439 } 440} 441 442template <class _Clock, class _Duration> 443_LIBCPP_HIDE_FROM_ABI void 444sleep_until(const chrono::time_point<_Clock, _Duration>& __t) 445{ 446 mutex __mut; 447 condition_variable __cv; 448 unique_lock<mutex> __lk(__mut); 449 while (_Clock::now() < __t) 450 __cv.wait_until(__lk, __t); 451} 452 453template <class _Duration> 454inline _LIBCPP_INLINE_VISIBILITY 455void 456sleep_until(const chrono::time_point<chrono::steady_clock, _Duration>& __t) 457{ 458 this_thread::sleep_for(__t - chrono::steady_clock::now()); 459} 460 461inline _LIBCPP_INLINE_VISIBILITY 462void yield() _NOEXCEPT {__libcpp_thread_yield();} 463 464} // namespace this_thread 465 466_LIBCPP_END_NAMESPACE_STD 467 468_LIBCPP_POP_MACROS 469 470#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 17 471# include <chrono> 472#endif 473 474#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 475# include <cstring> 476# include <functional> 477# include <new> 478# include <system_error> 479#endif 480 481#endif // _LIBCPP_THREAD 482