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 _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) 244 -> decltype(__parse_ctx.begin()) { 245 return __parser_.__parse(__parse_ctx, __format_spec::__fields_fill_align_width); 246 } 247 248 _LIBCPP_HIDE_FROM_ABI auto format(__thread_id __id, auto& __ctx) const -> decltype(__ctx.out()) { 249 // In __threading_support __libcpp_thread_id is either a 250 // unsigned long long or a pthread_t. 251 // 252 // The type of pthread_t is left unspecified in POSIX so it can be any 253 // type. The most logical types are an integral or pointer. 254 // On Linux systems pthread_t is an unsigned long long. 255 // On Apple systems pthread_t is a pointer type. 256 // 257 // Note the output should match what the stream operator does. Since 258 // the ostream operator has been shipped years before this formatter 259 // was added to the Standard, this formatter does what the stream 260 // operator does. This may require platform specific changes. 261 262 using _Tp = decltype(__get_underlying_id(__id)); 263 using _Cp = conditional_t<integral<_Tp>, _Tp, conditional_t<is_pointer_v<_Tp>, uintptr_t, void>>; 264 static_assert(!is_same_v<_Cp, void>, "unsupported thread::id type, please file a bug report"); 265 266 __format_spec::__parsed_specifications<_CharT> __specs = __parser_.__get_parsed_std_specifications(__ctx); 267 if constexpr (is_pointer_v<_Tp>) { 268 __specs.__std_.__alternate_form_ = true; 269 __specs.__std_.__type_ = __format_spec::__type::__hexadecimal_lower_case; 270 } 271 return __formatter::__format_integer(reinterpret_cast<_Cp>(__get_underlying_id(__id)), __ctx, __specs); 272 } 273 274 __format_spec::__parser<_CharT> __parser_{.__alignment_ = __format_spec::__alignment::__right}; 275}; 276#endif // _LIBCPP_STD_VER >= 23 277 278class _LIBCPP_TYPE_VIS thread 279{ 280 __libcpp_thread_t __t_; 281 282 thread(const thread&); 283 thread& operator=(const thread&); 284public: 285 typedef __thread_id id; 286 typedef __libcpp_thread_t native_handle_type; 287 288 _LIBCPP_INLINE_VISIBILITY 289 thread() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) {} 290#ifndef _LIBCPP_CXX03_LANG 291 template <class _Fp, class ..._Args, 292 class = __enable_if_t<!is_same<__remove_cvref_t<_Fp>, thread>::value> > 293 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS 294 explicit thread(_Fp&& __f, _Args&&... __args); 295#else // _LIBCPP_CXX03_LANG 296 template <class _Fp> 297 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS 298 explicit thread(_Fp __f); 299#endif 300 ~thread(); 301 302 _LIBCPP_INLINE_VISIBILITY 303 thread(thread&& __t) _NOEXCEPT : __t_(__t.__t_) { 304 __t.__t_ = _LIBCPP_NULL_THREAD; 305 } 306 307 _LIBCPP_INLINE_VISIBILITY 308 thread& operator=(thread&& __t) _NOEXCEPT { 309 if (!__libcpp_thread_isnull(&__t_)) 310 terminate(); 311 __t_ = __t.__t_; 312 __t.__t_ = _LIBCPP_NULL_THREAD; 313 return *this; 314 } 315 316 _LIBCPP_INLINE_VISIBILITY 317 void swap(thread& __t) _NOEXCEPT {_VSTD::swap(__t_, __t.__t_);} 318 319 _LIBCPP_INLINE_VISIBILITY 320 bool joinable() const _NOEXCEPT {return !__libcpp_thread_isnull(&__t_);} 321 void join(); 322 void detach(); 323 _LIBCPP_INLINE_VISIBILITY 324 id get_id() const _NOEXCEPT {return __libcpp_thread_get_id(&__t_);} 325 _LIBCPP_INLINE_VISIBILITY 326 native_handle_type native_handle() _NOEXCEPT {return __t_;} 327 328 static unsigned hardware_concurrency() _NOEXCEPT; 329}; 330 331#ifndef _LIBCPP_CXX03_LANG 332 333template <class _TSp, class _Fp, class ..._Args, size_t ..._Indices> 334inline _LIBCPP_INLINE_VISIBILITY 335void 336__thread_execute(tuple<_TSp, _Fp, _Args...>& __t, __tuple_indices<_Indices...>) 337{ 338 _VSTD::__invoke(_VSTD::move(_VSTD::get<1>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...); 339} 340 341template <class _Fp> 342_LIBCPP_INLINE_VISIBILITY 343void* __thread_proxy(void* __vp) 344{ 345 // _Fp = tuple< unique_ptr<__thread_struct>, Functor, Args...> 346 unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp)); 347 __thread_local_data().set_pointer(_VSTD::get<0>(*__p.get()).release()); 348 typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 2>::type _Index; 349 _VSTD::__thread_execute(*__p.get(), _Index()); 350 return nullptr; 351} 352 353template <class _Fp, class ..._Args, 354 class 355 > 356thread::thread(_Fp&& __f, _Args&&... __args) 357{ 358 typedef unique_ptr<__thread_struct> _TSPtr; 359 _TSPtr __tsp(new __thread_struct); 360 typedef tuple<_TSPtr, __decay_t<_Fp>, __decay_t<_Args>...> _Gp; 361 unique_ptr<_Gp> __p( 362 new _Gp(_VSTD::move(__tsp), 363 _VSTD::forward<_Fp>(__f), 364 _VSTD::forward<_Args>(__args)...)); 365 int __ec = _VSTD::__libcpp_thread_create(&__t_, &__thread_proxy<_Gp>, __p.get()); 366 if (__ec == 0) 367 __p.release(); 368 else 369 __throw_system_error(__ec, "thread constructor failed"); 370} 371 372#else // _LIBCPP_CXX03_LANG 373 374template <class _Fp> 375struct __thread_invoke_pair { 376 // This type is used to pass memory for thread local storage and a functor 377 // to a newly created thread because std::pair doesn't work with 378 // std::unique_ptr in C++03. 379 _LIBCPP_HIDE_FROM_ABI __thread_invoke_pair(_Fp& __f) : __tsp_(new __thread_struct), __fn_(__f) {} 380 unique_ptr<__thread_struct> __tsp_; 381 _Fp __fn_; 382}; 383 384template <class _Fp> 385_LIBCPP_HIDE_FROM_ABI void* __thread_proxy_cxx03(void* __vp) 386{ 387 unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp)); 388 __thread_local_data().set_pointer(__p->__tsp_.release()); 389 (__p->__fn_)(); 390 return nullptr; 391} 392 393template <class _Fp> 394thread::thread(_Fp __f) 395{ 396 397 typedef __thread_invoke_pair<_Fp> _InvokePair; 398 typedef unique_ptr<_InvokePair> _PairPtr; 399 _PairPtr __pp(new _InvokePair(__f)); 400 int __ec = _VSTD::__libcpp_thread_create(&__t_, &__thread_proxy_cxx03<_InvokePair>, __pp.get()); 401 if (__ec == 0) 402 __pp.release(); 403 else 404 __throw_system_error(__ec, "thread constructor failed"); 405} 406 407#endif // _LIBCPP_CXX03_LANG 408 409inline _LIBCPP_INLINE_VISIBILITY 410void swap(thread& __x, thread& __y) _NOEXCEPT {__x.swap(__y);} 411 412namespace this_thread 413{ 414 415_LIBCPP_FUNC_VIS void sleep_for(const chrono::nanoseconds& __ns); 416 417template <class _Rep, class _Period> 418_LIBCPP_HIDE_FROM_ABI void 419sleep_for(const chrono::duration<_Rep, _Period>& __d) 420{ 421 if (__d > chrono::duration<_Rep, _Period>::zero()) 422 { 423 // The standard guarantees a 64bit signed integer resolution for nanoseconds, 424 // so use INT64_MAX / 1e9 as cut-off point. Use a constant to avoid <climits> 425 // and issues with long double folding on PowerPC with GCC. 426 _LIBCPP_CONSTEXPR chrono::duration<long double> __max = 427 chrono::duration<long double>(9223372036.0L); 428 chrono::nanoseconds __ns; 429 if (__d < __max) 430 { 431 __ns = chrono::duration_cast<chrono::nanoseconds>(__d); 432 if (__ns < __d) 433 ++__ns; 434 } 435 else 436 __ns = chrono::nanoseconds::max(); 437 this_thread::sleep_for(__ns); 438 } 439} 440 441template <class _Clock, class _Duration> 442_LIBCPP_HIDE_FROM_ABI void 443sleep_until(const chrono::time_point<_Clock, _Duration>& __t) 444{ 445 mutex __mut; 446 condition_variable __cv; 447 unique_lock<mutex> __lk(__mut); 448 while (_Clock::now() < __t) 449 __cv.wait_until(__lk, __t); 450} 451 452template <class _Duration> 453inline _LIBCPP_INLINE_VISIBILITY 454void 455sleep_until(const chrono::time_point<chrono::steady_clock, _Duration>& __t) 456{ 457 this_thread::sleep_for(__t - chrono::steady_clock::now()); 458} 459 460inline _LIBCPP_INLINE_VISIBILITY 461void yield() _NOEXCEPT {__libcpp_thread_yield();} 462 463} // namespace this_thread 464 465_LIBCPP_END_NAMESPACE_STD 466 467_LIBCPP_POP_MACROS 468 469#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 17 470# include <chrono> 471#endif 472 473#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 474# include <cstring> 475# include <functional> 476# include <new> 477# include <system_error> 478#endif 479 480#endif // _LIBCPP_THREAD 481