138fd1498Szrj// <thread> -*- C++ -*- 238fd1498Szrj 338fd1498Szrj// Copyright (C) 2008-2018 Free Software Foundation, Inc. 438fd1498Szrj// 538fd1498Szrj// This file is part of the GNU ISO C++ Library. This library is free 638fd1498Szrj// software; you can redistribute it and/or modify it under the 738fd1498Szrj// terms of the GNU General Public License as published by the 838fd1498Szrj// Free Software Foundation; either version 3, or (at your option) 938fd1498Szrj// any later version. 1038fd1498Szrj 1138fd1498Szrj// This library is distributed in the hope that it will be useful, 1238fd1498Szrj// but WITHOUT ANY WARRANTY; without even the implied warranty of 1338fd1498Szrj// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1438fd1498Szrj// GNU General Public License for more details. 1538fd1498Szrj 1638fd1498Szrj// Under Section 7 of GPL version 3, you are granted additional 1738fd1498Szrj// permissions described in the GCC Runtime Library Exception, version 1838fd1498Szrj// 3.1, as published by the Free Software Foundation. 1938fd1498Szrj 2038fd1498Szrj// You should have received a copy of the GNU General Public License and 2138fd1498Szrj// a copy of the GCC Runtime Library Exception along with this program; 2238fd1498Szrj// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 2338fd1498Szrj// <http://www.gnu.org/licenses/>. 2438fd1498Szrj 2538fd1498Szrj/** @file include/thread 2638fd1498Szrj * This is a Standard C++ Library header. 2738fd1498Szrj */ 2838fd1498Szrj 2938fd1498Szrj#ifndef _GLIBCXX_THREAD 3038fd1498Szrj#define _GLIBCXX_THREAD 1 3138fd1498Szrj 3238fd1498Szrj#pragma GCC system_header 3338fd1498Szrj 3438fd1498Szrj#if __cplusplus < 201103L 3538fd1498Szrj# include <bits/c++0x_warning.h> 3638fd1498Szrj#else 3738fd1498Szrj 3838fd1498Szrj#include <chrono> 3938fd1498Szrj#include <memory> 4038fd1498Szrj#include <tuple> 4138fd1498Szrj#include <cerrno> 4238fd1498Szrj#include <bits/functexcept.h> 4338fd1498Szrj#include <bits/functional_hash.h> 4438fd1498Szrj#include <bits/invoke.h> 4538fd1498Szrj#include <bits/gthr.h> 4638fd1498Szrj 4738fd1498Szrj#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) 4838fd1498Szrj 4938fd1498Szrjnamespace std _GLIBCXX_VISIBILITY(default) 5038fd1498Szrj{ 5138fd1498Szrj_GLIBCXX_BEGIN_NAMESPACE_VERSION 5238fd1498Szrj 5338fd1498Szrj /** 5438fd1498Szrj * @defgroup threads Threads 5538fd1498Szrj * @ingroup concurrency 5638fd1498Szrj * 5738fd1498Szrj * Classes for thread support. 5838fd1498Szrj * @{ 5938fd1498Szrj */ 6038fd1498Szrj 6138fd1498Szrj /// thread 6238fd1498Szrj class thread 6338fd1498Szrj { 6438fd1498Szrj public: 6538fd1498Szrj // Abstract base class for types that wrap arbitrary functors to be 6638fd1498Szrj // invoked in the new thread of execution. 6738fd1498Szrj struct _State 6838fd1498Szrj { 6938fd1498Szrj virtual ~_State(); 7038fd1498Szrj virtual void _M_run() = 0; 7138fd1498Szrj }; 7238fd1498Szrj using _State_ptr = unique_ptr<_State>; 7338fd1498Szrj 7438fd1498Szrj typedef __gthread_t native_handle_type; 7538fd1498Szrj 7638fd1498Szrj /// thread::id 7738fd1498Szrj class id 7838fd1498Szrj { 7938fd1498Szrj native_handle_type _M_thread; 8038fd1498Szrj 8138fd1498Szrj public: 8238fd1498Szrj id() noexcept : _M_thread() { } 8338fd1498Szrj 8438fd1498Szrj explicit 8538fd1498Szrj id(native_handle_type __id) : _M_thread(__id) { } 8638fd1498Szrj 8738fd1498Szrj private: 8838fd1498Szrj friend class thread; 8938fd1498Szrj friend class hash<thread::id>; 9038fd1498Szrj 9138fd1498Szrj friend bool 9238fd1498Szrj operator==(thread::id __x, thread::id __y) noexcept; 9338fd1498Szrj 9438fd1498Szrj friend bool 9538fd1498Szrj operator<(thread::id __x, thread::id __y) noexcept; 9638fd1498Szrj 9738fd1498Szrj template<class _CharT, class _Traits> 9838fd1498Szrj friend basic_ostream<_CharT, _Traits>& 9938fd1498Szrj operator<<(basic_ostream<_CharT, _Traits>& __out, thread::id __id); 10038fd1498Szrj }; 10138fd1498Szrj 10238fd1498Szrj private: 10338fd1498Szrj id _M_id; 10438fd1498Szrj 10538fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS 10638fd1498Szrj // 2097. packaged_task constructors should be constrained 107*58e805e6Szrj template<typename _Tp> 108*58e805e6Szrj using __not_same = __not_<is_same< 109*58e805e6Szrj typename remove_cv<typename remove_reference<_Tp>::type>::type, 110*58e805e6Szrj thread>>; 11138fd1498Szrj 112*58e805e6Szrj public: 113*58e805e6Szrj thread() noexcept = default; 11438fd1498Szrj 115*58e805e6Szrj template<typename _Callable, typename... _Args, 116*58e805e6Szrj typename = _Require<__not_same<_Callable>>> 11738fd1498Szrj explicit 11838fd1498Szrj thread(_Callable&& __f, _Args&&... __args) 11938fd1498Szrj { 120*58e805e6Szrj static_assert( __is_invocable<typename decay<_Callable>::type, 121*58e805e6Szrj typename decay<_Args>::type...>::value, 122*58e805e6Szrj "std::thread arguments must be invocable after conversion to rvalues" 123*58e805e6Szrj ); 124*58e805e6Szrj 12538fd1498Szrj#ifdef GTHR_ACTIVE_PROXY 12638fd1498Szrj // Create a reference to pthread_create, not just the gthr weak symbol. 12738fd1498Szrj auto __depend = reinterpret_cast<void(*)()>(&pthread_create); 12838fd1498Szrj#else 12938fd1498Szrj auto __depend = nullptr; 13038fd1498Szrj#endif 13138fd1498Szrj _M_start_thread(_S_make_state( 13238fd1498Szrj __make_invoker(std::forward<_Callable>(__f), 13338fd1498Szrj std::forward<_Args>(__args)...)), 13438fd1498Szrj __depend); 13538fd1498Szrj } 13638fd1498Szrj 13738fd1498Szrj ~thread() 13838fd1498Szrj { 13938fd1498Szrj if (joinable()) 14038fd1498Szrj std::terminate(); 14138fd1498Szrj } 14238fd1498Szrj 143*58e805e6Szrj thread(const thread&) = delete; 144*58e805e6Szrj 145*58e805e6Szrj thread(thread&& __t) noexcept 146*58e805e6Szrj { swap(__t); } 147*58e805e6Szrj 14838fd1498Szrj thread& operator=(const thread&) = delete; 14938fd1498Szrj 15038fd1498Szrj thread& operator=(thread&& __t) noexcept 15138fd1498Szrj { 15238fd1498Szrj if (joinable()) 15338fd1498Szrj std::terminate(); 15438fd1498Szrj swap(__t); 15538fd1498Szrj return *this; 15638fd1498Szrj } 15738fd1498Szrj 15838fd1498Szrj void 15938fd1498Szrj swap(thread& __t) noexcept 16038fd1498Szrj { std::swap(_M_id, __t._M_id); } 16138fd1498Szrj 16238fd1498Szrj bool 16338fd1498Szrj joinable() const noexcept 16438fd1498Szrj { return !(_M_id == id()); } 16538fd1498Szrj 16638fd1498Szrj void 16738fd1498Szrj join(); 16838fd1498Szrj 16938fd1498Szrj void 17038fd1498Szrj detach(); 17138fd1498Szrj 17238fd1498Szrj thread::id 17338fd1498Szrj get_id() const noexcept 17438fd1498Szrj { return _M_id; } 17538fd1498Szrj 17638fd1498Szrj /** @pre thread is joinable 17738fd1498Szrj */ 17838fd1498Szrj native_handle_type 17938fd1498Szrj native_handle() 18038fd1498Szrj { return _M_id._M_thread; } 18138fd1498Szrj 18238fd1498Szrj // Returns a value that hints at the number of hardware thread contexts. 18338fd1498Szrj static unsigned int 18438fd1498Szrj hardware_concurrency() noexcept; 18538fd1498Szrj 18638fd1498Szrj private: 18738fd1498Szrj template<typename _Callable> 18838fd1498Szrj struct _State_impl : public _State 18938fd1498Szrj { 19038fd1498Szrj _Callable _M_func; 19138fd1498Szrj 19238fd1498Szrj _State_impl(_Callable&& __f) : _M_func(std::forward<_Callable>(__f)) 19338fd1498Szrj { } 19438fd1498Szrj 19538fd1498Szrj void 19638fd1498Szrj _M_run() { _M_func(); } 19738fd1498Szrj }; 19838fd1498Szrj 19938fd1498Szrj void 20038fd1498Szrj _M_start_thread(_State_ptr, void (*)()); 20138fd1498Szrj 20238fd1498Szrj template<typename _Callable> 20338fd1498Szrj static _State_ptr 20438fd1498Szrj _S_make_state(_Callable&& __f) 20538fd1498Szrj { 20638fd1498Szrj using _Impl = _State_impl<_Callable>; 20738fd1498Szrj return _State_ptr{new _Impl{std::forward<_Callable>(__f)}}; 20838fd1498Szrj } 20938fd1498Szrj#if _GLIBCXX_THREAD_ABI_COMPAT 21038fd1498Szrj public: 21138fd1498Szrj struct _Impl_base; 21238fd1498Szrj typedef shared_ptr<_Impl_base> __shared_base_type; 21338fd1498Szrj struct _Impl_base 21438fd1498Szrj { 21538fd1498Szrj __shared_base_type _M_this_ptr; 21638fd1498Szrj virtual ~_Impl_base() = default; 21738fd1498Szrj virtual void _M_run() = 0; 21838fd1498Szrj }; 21938fd1498Szrj 22038fd1498Szrj private: 22138fd1498Szrj void 22238fd1498Szrj _M_start_thread(__shared_base_type, void (*)()); 22338fd1498Szrj 22438fd1498Szrj void 22538fd1498Szrj _M_start_thread(__shared_base_type); 22638fd1498Szrj#endif 22738fd1498Szrj 22838fd1498Szrj private: 22938fd1498Szrj // A call wrapper that does INVOKE(forwarded tuple elements...) 23038fd1498Szrj template<typename _Tuple> 23138fd1498Szrj struct _Invoker 23238fd1498Szrj { 23338fd1498Szrj _Tuple _M_t; 23438fd1498Szrj 23538fd1498Szrj template<size_t _Index> 23638fd1498Szrj static __tuple_element_t<_Index, _Tuple>&& 23738fd1498Szrj _S_declval(); 23838fd1498Szrj 23938fd1498Szrj template<size_t... _Ind> 24038fd1498Szrj auto 24138fd1498Szrj _M_invoke(_Index_tuple<_Ind...>) 24238fd1498Szrj noexcept(noexcept(std::__invoke(_S_declval<_Ind>()...))) 24338fd1498Szrj -> decltype(std::__invoke(_S_declval<_Ind>()...)) 24438fd1498Szrj { return std::__invoke(std::get<_Ind>(std::move(_M_t))...); } 24538fd1498Szrj 24638fd1498Szrj using _Indices 24738fd1498Szrj = typename _Build_index_tuple<tuple_size<_Tuple>::value>::__type; 24838fd1498Szrj 24938fd1498Szrj auto 25038fd1498Szrj operator()() 25138fd1498Szrj noexcept(noexcept(std::declval<_Invoker&>()._M_invoke(_Indices()))) 25238fd1498Szrj -> decltype(std::declval<_Invoker&>()._M_invoke(_Indices())) 25338fd1498Szrj { return _M_invoke(_Indices()); } 25438fd1498Szrj }; 25538fd1498Szrj 25638fd1498Szrj template<typename... _Tp> 25738fd1498Szrj using __decayed_tuple = tuple<typename std::decay<_Tp>::type...>; 25838fd1498Szrj 25938fd1498Szrj public: 26038fd1498Szrj // Returns a call wrapper that stores 26138fd1498Szrj // tuple{DECAY_COPY(__callable), DECAY_COPY(__args)...}. 26238fd1498Szrj template<typename _Callable, typename... _Args> 26338fd1498Szrj static _Invoker<__decayed_tuple<_Callable, _Args...>> 26438fd1498Szrj __make_invoker(_Callable&& __callable, _Args&&... __args) 26538fd1498Szrj { 26638fd1498Szrj return { __decayed_tuple<_Callable, _Args...>{ 26738fd1498Szrj std::forward<_Callable>(__callable), std::forward<_Args>(__args)... 26838fd1498Szrj } }; 26938fd1498Szrj } 27038fd1498Szrj }; 27138fd1498Szrj 27238fd1498Szrj inline void 27338fd1498Szrj swap(thread& __x, thread& __y) noexcept 27438fd1498Szrj { __x.swap(__y); } 27538fd1498Szrj 27638fd1498Szrj inline bool 27738fd1498Szrj operator==(thread::id __x, thread::id __y) noexcept 27838fd1498Szrj { 27938fd1498Szrj // pthread_equal is undefined if either thread ID is not valid, so we 28038fd1498Szrj // can't safely use __gthread_equal on default-constructed values (nor 28138fd1498Szrj // the non-zero value returned by this_thread::get_id() for 28238fd1498Szrj // single-threaded programs using GNU libc). Assume EqualityComparable. 28338fd1498Szrj return __x._M_thread == __y._M_thread; 28438fd1498Szrj } 28538fd1498Szrj 28638fd1498Szrj inline bool 28738fd1498Szrj operator!=(thread::id __x, thread::id __y) noexcept 28838fd1498Szrj { return !(__x == __y); } 28938fd1498Szrj 29038fd1498Szrj inline bool 29138fd1498Szrj operator<(thread::id __x, thread::id __y) noexcept 29238fd1498Szrj { 29338fd1498Szrj // Pthreads doesn't define any way to do this, so we just have to 29438fd1498Szrj // assume native_handle_type is LessThanComparable. 29538fd1498Szrj return __x._M_thread < __y._M_thread; 29638fd1498Szrj } 29738fd1498Szrj 29838fd1498Szrj inline bool 29938fd1498Szrj operator<=(thread::id __x, thread::id __y) noexcept 30038fd1498Szrj { return !(__y < __x); } 30138fd1498Szrj 30238fd1498Szrj inline bool 30338fd1498Szrj operator>(thread::id __x, thread::id __y) noexcept 30438fd1498Szrj { return __y < __x; } 30538fd1498Szrj 30638fd1498Szrj inline bool 30738fd1498Szrj operator>=(thread::id __x, thread::id __y) noexcept 30838fd1498Szrj { return !(__x < __y); } 30938fd1498Szrj 31038fd1498Szrj // DR 889. 31138fd1498Szrj /// std::hash specialization for thread::id. 31238fd1498Szrj template<> 31338fd1498Szrj struct hash<thread::id> 31438fd1498Szrj : public __hash_base<size_t, thread::id> 31538fd1498Szrj { 31638fd1498Szrj size_t 31738fd1498Szrj operator()(const thread::id& __id) const noexcept 31838fd1498Szrj { return std::_Hash_impl::hash(__id._M_thread); } 31938fd1498Szrj }; 32038fd1498Szrj 32138fd1498Szrj template<class _CharT, class _Traits> 32238fd1498Szrj inline basic_ostream<_CharT, _Traits>& 32338fd1498Szrj operator<<(basic_ostream<_CharT, _Traits>& __out, thread::id __id) 32438fd1498Szrj { 32538fd1498Szrj if (__id == thread::id()) 32638fd1498Szrj return __out << "thread::id of a non-executing thread"; 32738fd1498Szrj else 32838fd1498Szrj return __out << __id._M_thread; 32938fd1498Szrj } 33038fd1498Szrj 33138fd1498Szrj /** @namespace std::this_thread 33238fd1498Szrj * @brief ISO C++ 2011 entities sub-namespace for thread. 33338fd1498Szrj * 30.3.2 Namespace this_thread. 33438fd1498Szrj */ 33538fd1498Szrj namespace this_thread 33638fd1498Szrj { 33738fd1498Szrj /// get_id 33838fd1498Szrj inline thread::id 33938fd1498Szrj get_id() noexcept 34038fd1498Szrj { 34138fd1498Szrj#ifdef __GLIBC__ 34238fd1498Szrj // For the GNU C library pthread_self() is usable without linking to 34338fd1498Szrj // libpthread.so but returns 0, so we cannot use it in single-threaded 34438fd1498Szrj // programs, because this_thread::get_id() != thread::id{} must be true. 34538fd1498Szrj // We know that pthread_t is an integral type in the GNU C library. 34638fd1498Szrj if (!__gthread_active_p()) 34738fd1498Szrj return thread::id(1); 34838fd1498Szrj#endif 34938fd1498Szrj return thread::id(__gthread_self()); 35038fd1498Szrj } 35138fd1498Szrj 35238fd1498Szrj /// yield 35338fd1498Szrj inline void 35438fd1498Szrj yield() noexcept 35538fd1498Szrj { 35638fd1498Szrj#ifdef _GLIBCXX_USE_SCHED_YIELD 35738fd1498Szrj __gthread_yield(); 35838fd1498Szrj#endif 35938fd1498Szrj } 36038fd1498Szrj 36138fd1498Szrj void 36238fd1498Szrj __sleep_for(chrono::seconds, chrono::nanoseconds); 36338fd1498Szrj 36438fd1498Szrj /// sleep_for 36538fd1498Szrj template<typename _Rep, typename _Period> 36638fd1498Szrj inline void 36738fd1498Szrj sleep_for(const chrono::duration<_Rep, _Period>& __rtime) 36838fd1498Szrj { 36938fd1498Szrj if (__rtime <= __rtime.zero()) 37038fd1498Szrj return; 37138fd1498Szrj auto __s = chrono::duration_cast<chrono::seconds>(__rtime); 37238fd1498Szrj auto __ns = chrono::duration_cast<chrono::nanoseconds>(__rtime - __s); 37338fd1498Szrj#ifdef _GLIBCXX_USE_NANOSLEEP 37438fd1498Szrj __gthread_time_t __ts = 37538fd1498Szrj { 37638fd1498Szrj static_cast<std::time_t>(__s.count()), 37738fd1498Szrj static_cast<long>(__ns.count()) 37838fd1498Szrj }; 37938fd1498Szrj while (::nanosleep(&__ts, &__ts) == -1 && errno == EINTR) 38038fd1498Szrj { } 38138fd1498Szrj#else 38238fd1498Szrj __sleep_for(__s, __ns); 38338fd1498Szrj#endif 38438fd1498Szrj } 38538fd1498Szrj 38638fd1498Szrj /// sleep_until 38738fd1498Szrj template<typename _Clock, typename _Duration> 38838fd1498Szrj inline void 38938fd1498Szrj sleep_until(const chrono::time_point<_Clock, _Duration>& __atime) 39038fd1498Szrj { 39138fd1498Szrj auto __now = _Clock::now(); 39238fd1498Szrj if (_Clock::is_steady) 39338fd1498Szrj { 39438fd1498Szrj if (__now < __atime) 39538fd1498Szrj sleep_for(__atime - __now); 39638fd1498Szrj return; 39738fd1498Szrj } 39838fd1498Szrj while (__now < __atime) 39938fd1498Szrj { 40038fd1498Szrj sleep_for(__atime - __now); 40138fd1498Szrj __now = _Clock::now(); 40238fd1498Szrj } 40338fd1498Szrj } 40438fd1498Szrj } 40538fd1498Szrj 40638fd1498Szrj // @} group threads 40738fd1498Szrj 40838fd1498Szrj_GLIBCXX_END_NAMESPACE_VERSION 40938fd1498Szrj} // namespace 41038fd1498Szrj 41138fd1498Szrj#endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1 41238fd1498Szrj 41338fd1498Szrj#endif // C++11 41438fd1498Szrj 41538fd1498Szrj#endif // _GLIBCXX_THREAD 416