xref: /netbsd-src/external/gpl3/gcc/dist/libstdc++-v3/include/bits/std_thread.h (revision b1e838363e3c6fc78a55519254d99869742dd33c)
1*b1e83836Smrg // std::thread declarations -*- C++ -*-
2*b1e83836Smrg 
3*b1e83836Smrg // Copyright (C) 2008-2022 Free Software Foundation, Inc.
4*b1e83836Smrg //
5*b1e83836Smrg // This file is part of the GNU ISO C++ Library.  This library is free
6*b1e83836Smrg // software; you can redistribute it and/or modify it under the
7*b1e83836Smrg // terms of the GNU General Public License as published by the
8*b1e83836Smrg // Free Software Foundation; either version 3, or (at your option)
9*b1e83836Smrg // any later version.
10*b1e83836Smrg 
11*b1e83836Smrg // This library is distributed in the hope that it will be useful,
12*b1e83836Smrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
13*b1e83836Smrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*b1e83836Smrg // GNU General Public License for more details.
15*b1e83836Smrg 
16*b1e83836Smrg // Under Section 7 of GPL version 3, you are granted additional
17*b1e83836Smrg // permissions described in the GCC Runtime Library Exception, version
18*b1e83836Smrg // 3.1, as published by the Free Software Foundation.
19*b1e83836Smrg 
20*b1e83836Smrg // You should have received a copy of the GNU General Public License and
21*b1e83836Smrg // a copy of the GCC Runtime Library Exception along with this program;
22*b1e83836Smrg // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23*b1e83836Smrg // <http://www.gnu.org/licenses/>.
24*b1e83836Smrg 
25*b1e83836Smrg /** @file bits/std_thread.h
26*b1e83836Smrg  *  This is an internal header file, included by other library headers.
27*b1e83836Smrg  *  Do not attempt to use it directly. @headername{thread}
28*b1e83836Smrg  */
29*b1e83836Smrg 
30*b1e83836Smrg #ifndef _GLIBCXX_THREAD_H
31*b1e83836Smrg #define _GLIBCXX_THREAD_H 1
32*b1e83836Smrg 
33*b1e83836Smrg #pragma GCC system_header
34*b1e83836Smrg 
35*b1e83836Smrg #if __cplusplus >= 201103L
36*b1e83836Smrg #include <bits/c++config.h>
37*b1e83836Smrg 
38*b1e83836Smrg #include <iosfwd>		// std::basic_ostream
39*b1e83836Smrg #include <tuple>		// std::tuple
40*b1e83836Smrg #include <bits/functional_hash.h> // std::hash
41*b1e83836Smrg #include <bits/invoke.h>	// std::__invoke
42*b1e83836Smrg #include <bits/refwrap.h>       // not required, but helpful to users
43*b1e83836Smrg #include <bits/unique_ptr.h>	// std::unique_ptr
44*b1e83836Smrg 
45*b1e83836Smrg #ifdef _GLIBCXX_HAS_GTHREADS
46*b1e83836Smrg # include <bits/gthr.h>
47*b1e83836Smrg #else
48*b1e83836Smrg # include <errno.h>
49*b1e83836Smrg # include <bits/functexcept.h>
50*b1e83836Smrg #endif
51*b1e83836Smrg 
_GLIBCXX_VISIBILITY(default)52*b1e83836Smrg namespace std _GLIBCXX_VISIBILITY(default)
53*b1e83836Smrg {
54*b1e83836Smrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
55*b1e83836Smrg 
56*b1e83836Smrg   /** @addtogroup threads
57*b1e83836Smrg    *  @{
58*b1e83836Smrg    */
59*b1e83836Smrg 
60*b1e83836Smrg   /** A std::thread represents a new thread of execution.
61*b1e83836Smrg    *
62*b1e83836Smrg    * The default constructor creates an object that does not own a thread.
63*b1e83836Smrg    * The `thread(F&&, Args&&...)` constructor invokes a callable in a new
64*b1e83836Smrg    * thread, and owns that new thread. A `std::thread` that owns a thread
65*b1e83836Smrg    * is *joinable*. Joining a thread waits for it to finish executing,
66*b1e83836Smrg    * which happens when the callable running in that thread returns.
67*b1e83836Smrg    *
68*b1e83836Smrg    * A `std::thread` cannot be copied, but can be moved. Moving a joinable
69*b1e83836Smrg    * object transfers ownership of its thread to another object.
70*b1e83836Smrg    *
71*b1e83836Smrg    * A joinable `std::thread` must be explicitly joined (or detached) before
72*b1e83836Smrg    * it is destroyed or assigned to. Attempting to destroy a joinable thread
73*b1e83836Smrg    * will terminate the whole process.
74*b1e83836Smrg    *
75*b1e83836Smrg    * @headerfile thread
76*b1e83836Smrg    * @since C++11
77*b1e83836Smrg    */
78*b1e83836Smrg   class thread
79*b1e83836Smrg   {
80*b1e83836Smrg   public:
81*b1e83836Smrg #ifdef _GLIBCXX_HAS_GTHREADS
82*b1e83836Smrg     // Abstract base class for types that wrap arbitrary functors to be
83*b1e83836Smrg     // invoked in the new thread of execution.
84*b1e83836Smrg     struct _State
85*b1e83836Smrg     {
86*b1e83836Smrg       virtual ~_State();
87*b1e83836Smrg       virtual void _M_run() = 0;
88*b1e83836Smrg     };
89*b1e83836Smrg     using _State_ptr = unique_ptr<_State>;
90*b1e83836Smrg 
91*b1e83836Smrg     using native_handle_type = __gthread_t;
92*b1e83836Smrg #else
93*b1e83836Smrg     using native_handle_type = int;
94*b1e83836Smrg #endif
95*b1e83836Smrg 
96*b1e83836Smrg     /** A std::thread::id is a unique identifier for a thread.
97*b1e83836Smrg      *
98*b1e83836Smrg      * @headerfile thread
99*b1e83836Smrg      * @since C++11
100*b1e83836Smrg      */
101*b1e83836Smrg     class id
102*b1e83836Smrg     {
103*b1e83836Smrg       native_handle_type	_M_thread;
104*b1e83836Smrg 
105*b1e83836Smrg     public:
106*b1e83836Smrg       id() noexcept : _M_thread() { }
107*b1e83836Smrg 
108*b1e83836Smrg       explicit
109*b1e83836Smrg       id(native_handle_type __id) : _M_thread(__id) { }
110*b1e83836Smrg 
111*b1e83836Smrg     private:
112*b1e83836Smrg       friend class thread;
113*b1e83836Smrg       friend struct hash<id>;
114*b1e83836Smrg 
115*b1e83836Smrg       friend bool
116*b1e83836Smrg       operator==(id __x, id __y) noexcept;
117*b1e83836Smrg 
118*b1e83836Smrg #if __cpp_lib_three_way_comparison
119*b1e83836Smrg       friend strong_ordering
120*b1e83836Smrg       operator<=>(id __x, id __y) noexcept;
121*b1e83836Smrg #else
122*b1e83836Smrg       friend bool
123*b1e83836Smrg       operator<(id __x, id __y) noexcept;
124*b1e83836Smrg #endif
125*b1e83836Smrg 
126*b1e83836Smrg       template<class _CharT, class _Traits>
127*b1e83836Smrg 	friend basic_ostream<_CharT, _Traits>&
128*b1e83836Smrg 	operator<<(basic_ostream<_CharT, _Traits>& __out, id __id);
129*b1e83836Smrg     };
130*b1e83836Smrg 
131*b1e83836Smrg   private:
132*b1e83836Smrg     id				_M_id;
133*b1e83836Smrg 
134*b1e83836Smrg     // _GLIBCXX_RESOLVE_LIB_DEFECTS
135*b1e83836Smrg     // 2097.  packaged_task constructors should be constrained
136*b1e83836Smrg     // 3039. Unnecessary decay in thread and packaged_task
137*b1e83836Smrg     template<typename _Tp>
138*b1e83836Smrg       using __not_same = __not_<is_same<__remove_cvref_t<_Tp>, thread>>;
139*b1e83836Smrg 
140*b1e83836Smrg   public:
141*b1e83836Smrg     thread() noexcept = default;
142*b1e83836Smrg 
143*b1e83836Smrg #ifdef _GLIBCXX_HAS_GTHREADS
144*b1e83836Smrg     template<typename _Callable, typename... _Args,
145*b1e83836Smrg 	     typename = _Require<__not_same<_Callable>>>
146*b1e83836Smrg       explicit
147*b1e83836Smrg       thread(_Callable&& __f, _Args&&... __args)
148*b1e83836Smrg       {
149*b1e83836Smrg 	static_assert( __is_invocable<typename decay<_Callable>::type,
150*b1e83836Smrg 				      typename decay<_Args>::type...>::value,
151*b1e83836Smrg 	  "std::thread arguments must be invocable after conversion to rvalues"
152*b1e83836Smrg 	  );
153*b1e83836Smrg 
154*b1e83836Smrg #ifdef GTHR_ACTIVE_PROXY
155*b1e83836Smrg 	// Create a reference to pthread_create, not just the gthr weak symbol.
156*b1e83836Smrg 	auto __depend = reinterpret_cast<void(*)()>(&pthread_create);
157*b1e83836Smrg #else
158*b1e83836Smrg 	auto __depend = nullptr;
159*b1e83836Smrg #endif
160*b1e83836Smrg 	using _Wrapper = _Call_wrapper<_Callable, _Args...>;
161*b1e83836Smrg 	// Create a call wrapper with DECAY_COPY(__f) as its target object
162*b1e83836Smrg 	// and DECAY_COPY(__args)... as its bound argument entities.
163*b1e83836Smrg 	_M_start_thread(_State_ptr(new _State_impl<_Wrapper>(
164*b1e83836Smrg 	      std::forward<_Callable>(__f), std::forward<_Args>(__args)...)),
165*b1e83836Smrg 	    __depend);
166*b1e83836Smrg       }
167*b1e83836Smrg #endif // _GLIBCXX_HAS_GTHREADS
168*b1e83836Smrg 
169*b1e83836Smrg     ~thread()
170*b1e83836Smrg     {
171*b1e83836Smrg       if (joinable())
172*b1e83836Smrg 	std::__terminate();
173*b1e83836Smrg     }
174*b1e83836Smrg 
175*b1e83836Smrg     thread(const thread&) = delete;
176*b1e83836Smrg 
177*b1e83836Smrg     thread(thread&& __t) noexcept
178*b1e83836Smrg     { swap(__t); }
179*b1e83836Smrg 
180*b1e83836Smrg     thread& operator=(const thread&) = delete;
181*b1e83836Smrg 
182*b1e83836Smrg     thread& operator=(thread&& __t) noexcept
183*b1e83836Smrg     {
184*b1e83836Smrg       if (joinable())
185*b1e83836Smrg 	std::__terminate();
186*b1e83836Smrg       swap(__t);
187*b1e83836Smrg       return *this;
188*b1e83836Smrg     }
189*b1e83836Smrg 
190*b1e83836Smrg     void
191*b1e83836Smrg     swap(thread& __t) noexcept
192*b1e83836Smrg     { std::swap(_M_id, __t._M_id); }
193*b1e83836Smrg 
194*b1e83836Smrg     bool
195*b1e83836Smrg     joinable() const noexcept
196*b1e83836Smrg     { return !(_M_id == id()); }
197*b1e83836Smrg 
198*b1e83836Smrg     void
199*b1e83836Smrg     join();
200*b1e83836Smrg 
201*b1e83836Smrg     void
202*b1e83836Smrg     detach();
203*b1e83836Smrg 
204*b1e83836Smrg     id
205*b1e83836Smrg     get_id() const noexcept
206*b1e83836Smrg     { return _M_id; }
207*b1e83836Smrg 
208*b1e83836Smrg     /** @pre thread is joinable
209*b1e83836Smrg      */
210*b1e83836Smrg     native_handle_type
211*b1e83836Smrg     native_handle()
212*b1e83836Smrg     { return _M_id._M_thread; }
213*b1e83836Smrg 
214*b1e83836Smrg     // Returns a value that hints at the number of hardware thread contexts.
215*b1e83836Smrg     static unsigned int
216*b1e83836Smrg     hardware_concurrency() noexcept;
217*b1e83836Smrg 
218*b1e83836Smrg #ifdef _GLIBCXX_HAS_GTHREADS
219*b1e83836Smrg   private:
220*b1e83836Smrg     template<typename _Callable>
221*b1e83836Smrg       struct _State_impl : public _State
222*b1e83836Smrg       {
223*b1e83836Smrg 	_Callable		_M_func;
224*b1e83836Smrg 
225*b1e83836Smrg 	template<typename... _Args>
226*b1e83836Smrg 	  _State_impl(_Args&&... __args)
227*b1e83836Smrg 	  : _M_func(std::forward<_Args>(__args)...)
228*b1e83836Smrg 	  { }
229*b1e83836Smrg 
230*b1e83836Smrg 	void
231*b1e83836Smrg 	_M_run() { _M_func(); }
232*b1e83836Smrg       };
233*b1e83836Smrg 
234*b1e83836Smrg     void
235*b1e83836Smrg     _M_start_thread(_State_ptr, void (*)());
236*b1e83836Smrg 
237*b1e83836Smrg #if _GLIBCXX_THREAD_ABI_COMPAT
238*b1e83836Smrg   public:
239*b1e83836Smrg     struct _Impl_base;
240*b1e83836Smrg     typedef shared_ptr<_Impl_base>	__shared_base_type;
241*b1e83836Smrg     struct _Impl_base
242*b1e83836Smrg     {
243*b1e83836Smrg       __shared_base_type	_M_this_ptr;
244*b1e83836Smrg       virtual ~_Impl_base() = default;
245*b1e83836Smrg       virtual void _M_run() = 0;
246*b1e83836Smrg     };
247*b1e83836Smrg 
248*b1e83836Smrg   private:
249*b1e83836Smrg     void
250*b1e83836Smrg     _M_start_thread(__shared_base_type, void (*)());
251*b1e83836Smrg 
252*b1e83836Smrg     void
253*b1e83836Smrg     _M_start_thread(__shared_base_type);
254*b1e83836Smrg #endif
255*b1e83836Smrg 
256*b1e83836Smrg   private:
257*b1e83836Smrg     // A call wrapper that does INVOKE(forwarded tuple elements...)
258*b1e83836Smrg     template<typename _Tuple>
259*b1e83836Smrg       struct _Invoker
260*b1e83836Smrg       {
261*b1e83836Smrg 	template<typename... _Args>
262*b1e83836Smrg 	  explicit
263*b1e83836Smrg 	  _Invoker(_Args&&... __args)
264*b1e83836Smrg 	  : _M_t(std::forward<_Args>(__args)...)
265*b1e83836Smrg 	  { }
266*b1e83836Smrg 
267*b1e83836Smrg 	_Tuple _M_t;
268*b1e83836Smrg 
269*b1e83836Smrg 	template<typename>
270*b1e83836Smrg 	  struct __result;
271*b1e83836Smrg 	template<typename _Fn, typename... _Args>
272*b1e83836Smrg 	  struct __result<tuple<_Fn, _Args...>>
273*b1e83836Smrg 	  : __invoke_result<_Fn, _Args...>
274*b1e83836Smrg 	  { };
275*b1e83836Smrg 
276*b1e83836Smrg 	template<size_t... _Ind>
277*b1e83836Smrg 	  typename __result<_Tuple>::type
278*b1e83836Smrg 	  _M_invoke(_Index_tuple<_Ind...>)
279*b1e83836Smrg 	  { return std::__invoke(std::get<_Ind>(std::move(_M_t))...); }
280*b1e83836Smrg 
281*b1e83836Smrg 	typename __result<_Tuple>::type
282*b1e83836Smrg 	operator()()
283*b1e83836Smrg 	{
284*b1e83836Smrg 	  using _Indices
285*b1e83836Smrg 	    = typename _Build_index_tuple<tuple_size<_Tuple>::value>::__type;
286*b1e83836Smrg 	  return _M_invoke(_Indices());
287*b1e83836Smrg 	}
288*b1e83836Smrg       };
289*b1e83836Smrg 
290*b1e83836Smrg   public:
291*b1e83836Smrg     /// @cond undocumented
292*b1e83836Smrg     template<typename... _Tp>
293*b1e83836Smrg       using _Call_wrapper = _Invoker<tuple<typename decay<_Tp>::type...>>;
294*b1e83836Smrg     /// @endcond
295*b1e83836Smrg #endif // _GLIBCXX_HAS_GTHREADS
296*b1e83836Smrg   };
297*b1e83836Smrg 
298*b1e83836Smrg #ifndef _GLIBCXX_HAS_GTHREADS
299*b1e83836Smrg   inline void thread::join() { std::__throw_system_error(EINVAL); }
300*b1e83836Smrg   inline void thread::detach() { std::__throw_system_error(EINVAL); }
301*b1e83836Smrg   inline unsigned int thread::hardware_concurrency() noexcept { return 0; }
302*b1e83836Smrg #endif
303*b1e83836Smrg 
304*b1e83836Smrg   /// @relates std::thread
305*b1e83836Smrg   inline void
306*b1e83836Smrg   swap(thread& __x, thread& __y) noexcept
307*b1e83836Smrg   { __x.swap(__y); }
308*b1e83836Smrg 
309*b1e83836Smrg   /// @relates std::thread::id
310*b1e83836Smrg   inline bool
311*b1e83836Smrg   operator==(thread::id __x, thread::id __y) noexcept
312*b1e83836Smrg   {
313*b1e83836Smrg     // pthread_equal is undefined if either thread ID is not valid, so we
314*b1e83836Smrg     // can't safely use __gthread_equal on default-constructed values (nor
315*b1e83836Smrg     // the non-zero value returned by this_thread::get_id() for
316*b1e83836Smrg     // single-threaded programs using GNU libc). Assume EqualityComparable.
317*b1e83836Smrg     return __x._M_thread == __y._M_thread;
318*b1e83836Smrg   }
319*b1e83836Smrg 
320*b1e83836Smrg   // N.B. other comparison operators are defined in <thread>
321*b1e83836Smrg 
322*b1e83836Smrg   // DR 889.
323*b1e83836Smrg   /// std::hash specialization for thread::id.
324*b1e83836Smrg   template<>
325*b1e83836Smrg     struct hash<thread::id>
326*b1e83836Smrg     : public __hash_base<size_t, thread::id>
327*b1e83836Smrg     {
328*b1e83836Smrg       size_t
329*b1e83836Smrg       operator()(const thread::id& __id) const noexcept
330*b1e83836Smrg       { return std::_Hash_impl::hash(__id._M_thread); }
331*b1e83836Smrg     };
332*b1e83836Smrg 
333*b1e83836Smrg   namespace this_thread
334*b1e83836Smrg   {
335*b1e83836Smrg     /// The unique identifier of the current thread.
336*b1e83836Smrg     inline thread::id
337*b1e83836Smrg     get_id() noexcept
338*b1e83836Smrg     {
339*b1e83836Smrg #ifndef _GLIBCXX_HAS_GTHREADS
340*b1e83836Smrg       return thread::id(1);
341*b1e83836Smrg #elif defined _GLIBCXX_NATIVE_THREAD_ID
342*b1e83836Smrg       return thread::id(_GLIBCXX_NATIVE_THREAD_ID);
343*b1e83836Smrg #else
344*b1e83836Smrg       return thread::id(__gthread_self());
345*b1e83836Smrg #endif
346*b1e83836Smrg     }
347*b1e83836Smrg 
348*b1e83836Smrg     /// Allow the implementation to schedule a different thread.
349*b1e83836Smrg     inline void
350*b1e83836Smrg     yield() noexcept
351*b1e83836Smrg     {
352*b1e83836Smrg #if defined _GLIBCXX_HAS_GTHREADS && defined _GLIBCXX_USE_SCHED_YIELD
353*b1e83836Smrg       __gthread_yield();
354*b1e83836Smrg #endif
355*b1e83836Smrg     }
356*b1e83836Smrg 
357*b1e83836Smrg   } // namespace this_thread
358*b1e83836Smrg 
359*b1e83836Smrg   /// @}
360*b1e83836Smrg 
361*b1e83836Smrg _GLIBCXX_END_NAMESPACE_VERSION
362*b1e83836Smrg } // namespace
363*b1e83836Smrg #endif // C++11
364*b1e83836Smrg 
365*b1e83836Smrg #endif // _GLIBCXX_THREAD_H
366