annotate libcxx/include/thread @ 220:42394fc6a535

Added tag llvm12 for changeset 0572611fdcc8
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Tue, 15 Jun 2021 19:13:43 +0900
parents 1d019706d866
children 2e18cbf3894f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 // -*- C++ -*-
anatofuz
parents:
diff changeset
2 //===--------------------------- thread -----------------------------------===//
anatofuz
parents:
diff changeset
3 //
anatofuz
parents:
diff changeset
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
anatofuz
parents:
diff changeset
5 // See https://llvm.org/LICENSE.txt for license information.
anatofuz
parents:
diff changeset
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
anatofuz
parents:
diff changeset
7 //
anatofuz
parents:
diff changeset
8 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
9
anatofuz
parents:
diff changeset
10 #ifndef _LIBCPP_THREAD
anatofuz
parents:
diff changeset
11 #define _LIBCPP_THREAD
anatofuz
parents:
diff changeset
12
anatofuz
parents:
diff changeset
13 /*
anatofuz
parents:
diff changeset
14
anatofuz
parents:
diff changeset
15 thread synopsis
anatofuz
parents:
diff changeset
16
anatofuz
parents:
diff changeset
17 namespace std
anatofuz
parents:
diff changeset
18 {
anatofuz
parents:
diff changeset
19
anatofuz
parents:
diff changeset
20 class thread
anatofuz
parents:
diff changeset
21 {
anatofuz
parents:
diff changeset
22 public:
anatofuz
parents:
diff changeset
23 class id;
anatofuz
parents:
diff changeset
24 typedef pthread_t native_handle_type;
anatofuz
parents:
diff changeset
25
anatofuz
parents:
diff changeset
26 thread() noexcept;
anatofuz
parents:
diff changeset
27 template <class F, class ...Args> explicit thread(F&& f, Args&&... args);
anatofuz
parents:
diff changeset
28 ~thread();
anatofuz
parents:
diff changeset
29
anatofuz
parents:
diff changeset
30 thread(const thread&) = delete;
anatofuz
parents:
diff changeset
31 thread(thread&& t) noexcept;
anatofuz
parents:
diff changeset
32
anatofuz
parents:
diff changeset
33 thread& operator=(const thread&) = delete;
anatofuz
parents:
diff changeset
34 thread& operator=(thread&& t) noexcept;
anatofuz
parents:
diff changeset
35
anatofuz
parents:
diff changeset
36 void swap(thread& t) noexcept;
anatofuz
parents:
diff changeset
37
anatofuz
parents:
diff changeset
38 bool joinable() const noexcept;
anatofuz
parents:
diff changeset
39 void join();
anatofuz
parents:
diff changeset
40 void detach();
anatofuz
parents:
diff changeset
41 id get_id() const noexcept;
anatofuz
parents:
diff changeset
42 native_handle_type native_handle();
anatofuz
parents:
diff changeset
43
anatofuz
parents:
diff changeset
44 static unsigned hardware_concurrency() noexcept;
anatofuz
parents:
diff changeset
45 };
anatofuz
parents:
diff changeset
46
anatofuz
parents:
diff changeset
47 void swap(thread& x, thread& y) noexcept;
anatofuz
parents:
diff changeset
48
anatofuz
parents:
diff changeset
49 class thread::id
anatofuz
parents:
diff changeset
50 {
anatofuz
parents:
diff changeset
51 public:
anatofuz
parents:
diff changeset
52 id() noexcept;
anatofuz
parents:
diff changeset
53 };
anatofuz
parents:
diff changeset
54
anatofuz
parents:
diff changeset
55 bool operator==(thread::id x, thread::id y) noexcept;
anatofuz
parents:
diff changeset
56 bool operator!=(thread::id x, thread::id y) noexcept;
anatofuz
parents:
diff changeset
57 bool operator< (thread::id x, thread::id y) noexcept;
anatofuz
parents:
diff changeset
58 bool operator<=(thread::id x, thread::id y) noexcept;
anatofuz
parents:
diff changeset
59 bool operator> (thread::id x, thread::id y) noexcept;
anatofuz
parents:
diff changeset
60 bool operator>=(thread::id x, thread::id y) noexcept;
anatofuz
parents:
diff changeset
61
anatofuz
parents:
diff changeset
62 template<class charT, class traits>
anatofuz
parents:
diff changeset
63 basic_ostream<charT, traits>&
anatofuz
parents:
diff changeset
64 operator<<(basic_ostream<charT, traits>& out, thread::id id);
anatofuz
parents:
diff changeset
65
anatofuz
parents:
diff changeset
66 namespace this_thread
anatofuz
parents:
diff changeset
67 {
anatofuz
parents:
diff changeset
68
anatofuz
parents:
diff changeset
69 thread::id get_id() noexcept;
anatofuz
parents:
diff changeset
70
anatofuz
parents:
diff changeset
71 void yield() noexcept;
anatofuz
parents:
diff changeset
72
anatofuz
parents:
diff changeset
73 template <class Clock, class Duration>
anatofuz
parents:
diff changeset
74 void sleep_until(const chrono::time_point<Clock, Duration>& abs_time);
anatofuz
parents:
diff changeset
75
anatofuz
parents:
diff changeset
76 template <class Rep, class Period>
anatofuz
parents:
diff changeset
77 void sleep_for(const chrono::duration<Rep, Period>& rel_time);
anatofuz
parents:
diff changeset
78
anatofuz
parents:
diff changeset
79 } // this_thread
anatofuz
parents:
diff changeset
80
anatofuz
parents:
diff changeset
81 } // std
anatofuz
parents:
diff changeset
82
anatofuz
parents:
diff changeset
83 */
anatofuz
parents:
diff changeset
84
anatofuz
parents:
diff changeset
85 #include <__config>
anatofuz
parents:
diff changeset
86 #include <iosfwd>
anatofuz
parents:
diff changeset
87 #include <__functional_base>
anatofuz
parents:
diff changeset
88 #include <type_traits>
anatofuz
parents:
diff changeset
89 #include <cstddef>
anatofuz
parents:
diff changeset
90 #include <functional>
anatofuz
parents:
diff changeset
91 #include <memory>
anatofuz
parents:
diff changeset
92 #include <system_error>
anatofuz
parents:
diff changeset
93 #include <chrono>
anatofuz
parents:
diff changeset
94 #include <__mutex_base>
anatofuz
parents:
diff changeset
95 #ifndef _LIBCPP_CXX03_LANG
anatofuz
parents:
diff changeset
96 #include <tuple>
anatofuz
parents:
diff changeset
97 #endif
anatofuz
parents:
diff changeset
98 #include <__threading_support>
anatofuz
parents:
diff changeset
99 #include <__debug>
anatofuz
parents:
diff changeset
100
anatofuz
parents:
diff changeset
101 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
anatofuz
parents:
diff changeset
102 #pragma GCC system_header
anatofuz
parents:
diff changeset
103 #endif
anatofuz
parents:
diff changeset
104
anatofuz
parents:
diff changeset
105 _LIBCPP_PUSH_MACROS
anatofuz
parents:
diff changeset
106 #include <__undef_macros>
anatofuz
parents:
diff changeset
107
anatofuz
parents:
diff changeset
108 #ifdef _LIBCPP_HAS_NO_THREADS
anatofuz
parents:
diff changeset
109 #error <thread> is not supported on this single threaded system
anatofuz
parents:
diff changeset
110 #else // !_LIBCPP_HAS_NO_THREADS
anatofuz
parents:
diff changeset
111
anatofuz
parents:
diff changeset
112 _LIBCPP_BEGIN_NAMESPACE_STD
anatofuz
parents:
diff changeset
113
anatofuz
parents:
diff changeset
114 template <class _Tp> class __thread_specific_ptr;
anatofuz
parents:
diff changeset
115 class _LIBCPP_TYPE_VIS __thread_struct;
anatofuz
parents:
diff changeset
116 class _LIBCPP_HIDDEN __thread_struct_imp;
anatofuz
parents:
diff changeset
117 class __assoc_sub_state;
anatofuz
parents:
diff changeset
118
anatofuz
parents:
diff changeset
119 _LIBCPP_FUNC_VIS __thread_specific_ptr<__thread_struct>& __thread_local_data();
anatofuz
parents:
diff changeset
120
anatofuz
parents:
diff changeset
121 class _LIBCPP_TYPE_VIS __thread_struct
anatofuz
parents:
diff changeset
122 {
anatofuz
parents:
diff changeset
123 __thread_struct_imp* __p_;
anatofuz
parents:
diff changeset
124
anatofuz
parents:
diff changeset
125 __thread_struct(const __thread_struct&);
anatofuz
parents:
diff changeset
126 __thread_struct& operator=(const __thread_struct&);
anatofuz
parents:
diff changeset
127 public:
anatofuz
parents:
diff changeset
128 __thread_struct();
anatofuz
parents:
diff changeset
129 ~__thread_struct();
anatofuz
parents:
diff changeset
130
anatofuz
parents:
diff changeset
131 void notify_all_at_thread_exit(condition_variable*, mutex*);
anatofuz
parents:
diff changeset
132 void __make_ready_at_thread_exit(__assoc_sub_state*);
anatofuz
parents:
diff changeset
133 };
anatofuz
parents:
diff changeset
134
anatofuz
parents:
diff changeset
135 template <class _Tp>
anatofuz
parents:
diff changeset
136 class __thread_specific_ptr
anatofuz
parents:
diff changeset
137 {
anatofuz
parents:
diff changeset
138 __libcpp_tls_key __key_;
anatofuz
parents:
diff changeset
139
anatofuz
parents:
diff changeset
140 // Only __thread_local_data() may construct a __thread_specific_ptr
anatofuz
parents:
diff changeset
141 // and only with _Tp == __thread_struct.
anatofuz
parents:
diff changeset
142 static_assert((is_same<_Tp, __thread_struct>::value), "");
anatofuz
parents:
diff changeset
143 __thread_specific_ptr();
anatofuz
parents:
diff changeset
144 friend _LIBCPP_FUNC_VIS __thread_specific_ptr<__thread_struct>& __thread_local_data();
anatofuz
parents:
diff changeset
145
anatofuz
parents:
diff changeset
146 __thread_specific_ptr(const __thread_specific_ptr&);
anatofuz
parents:
diff changeset
147 __thread_specific_ptr& operator=(const __thread_specific_ptr&);
anatofuz
parents:
diff changeset
148
anatofuz
parents:
diff changeset
149 _LIBCPP_HIDDEN static void _LIBCPP_TLS_DESTRUCTOR_CC __at_thread_exit(void*);
anatofuz
parents:
diff changeset
150
anatofuz
parents:
diff changeset
151 public:
anatofuz
parents:
diff changeset
152 typedef _Tp* pointer;
anatofuz
parents:
diff changeset
153
anatofuz
parents:
diff changeset
154 ~__thread_specific_ptr();
anatofuz
parents:
diff changeset
155
anatofuz
parents:
diff changeset
156 _LIBCPP_INLINE_VISIBILITY
anatofuz
parents:
diff changeset
157 pointer get() const {return static_cast<_Tp*>(__libcpp_tls_get(__key_));}
anatofuz
parents:
diff changeset
158 _LIBCPP_INLINE_VISIBILITY
anatofuz
parents:
diff changeset
159 pointer operator*() const {return *get();}
anatofuz
parents:
diff changeset
160 _LIBCPP_INLINE_VISIBILITY
anatofuz
parents:
diff changeset
161 pointer operator->() const {return get();}
anatofuz
parents:
diff changeset
162 void set_pointer(pointer __p);
anatofuz
parents:
diff changeset
163 };
anatofuz
parents:
diff changeset
164
anatofuz
parents:
diff changeset
165 template <class _Tp>
anatofuz
parents:
diff changeset
166 void _LIBCPP_TLS_DESTRUCTOR_CC
anatofuz
parents:
diff changeset
167 __thread_specific_ptr<_Tp>::__at_thread_exit(void* __p)
anatofuz
parents:
diff changeset
168 {
anatofuz
parents:
diff changeset
169 delete static_cast<pointer>(__p);
anatofuz
parents:
diff changeset
170 }
anatofuz
parents:
diff changeset
171
anatofuz
parents:
diff changeset
172 template <class _Tp>
anatofuz
parents:
diff changeset
173 __thread_specific_ptr<_Tp>::__thread_specific_ptr()
anatofuz
parents:
diff changeset
174 {
anatofuz
parents:
diff changeset
175 int __ec =
anatofuz
parents:
diff changeset
176 __libcpp_tls_create(&__key_, &__thread_specific_ptr::__at_thread_exit);
anatofuz
parents:
diff changeset
177 if (__ec)
anatofuz
parents:
diff changeset
178 __throw_system_error(__ec, "__thread_specific_ptr construction failed");
anatofuz
parents:
diff changeset
179 }
anatofuz
parents:
diff changeset
180
anatofuz
parents:
diff changeset
181 template <class _Tp>
anatofuz
parents:
diff changeset
182 __thread_specific_ptr<_Tp>::~__thread_specific_ptr()
anatofuz
parents:
diff changeset
183 {
anatofuz
parents:
diff changeset
184 // __thread_specific_ptr is only created with a static storage duration
anatofuz
parents:
diff changeset
185 // so this destructor is only invoked during program termination. Invoking
anatofuz
parents:
diff changeset
186 // pthread_key_delete(__key_) may prevent other threads from deleting their
anatofuz
parents:
diff changeset
187 // thread local data. For this reason we leak the key.
anatofuz
parents:
diff changeset
188 }
anatofuz
parents:
diff changeset
189
anatofuz
parents:
diff changeset
190 template <class _Tp>
anatofuz
parents:
diff changeset
191 void
anatofuz
parents:
diff changeset
192 __thread_specific_ptr<_Tp>::set_pointer(pointer __p)
anatofuz
parents:
diff changeset
193 {
anatofuz
parents:
diff changeset
194 _LIBCPP_ASSERT(get() == nullptr,
anatofuz
parents:
diff changeset
195 "Attempting to overwrite thread local data");
anatofuz
parents:
diff changeset
196 __libcpp_tls_set(__key_, __p);
anatofuz
parents:
diff changeset
197 }
anatofuz
parents:
diff changeset
198
anatofuz
parents:
diff changeset
199 template<>
anatofuz
parents:
diff changeset
200 struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>
anatofuz
parents:
diff changeset
201 : public unary_function<__thread_id, size_t>
anatofuz
parents:
diff changeset
202 {
anatofuz
parents:
diff changeset
203 _LIBCPP_INLINE_VISIBILITY
anatofuz
parents:
diff changeset
204 size_t operator()(__thread_id __v) const _NOEXCEPT
anatofuz
parents:
diff changeset
205 {
anatofuz
parents:
diff changeset
206 return hash<__libcpp_thread_id>()(__v.__id_);
anatofuz
parents:
diff changeset
207 }
anatofuz
parents:
diff changeset
208 };
anatofuz
parents:
diff changeset
209
anatofuz
parents:
diff changeset
210 template<class _CharT, class _Traits>
anatofuz
parents:
diff changeset
211 _LIBCPP_INLINE_VISIBILITY
anatofuz
parents:
diff changeset
212 basic_ostream<_CharT, _Traits>&
anatofuz
parents:
diff changeset
213 operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id)
anatofuz
parents:
diff changeset
214 {return __os << __id.__id_;}
anatofuz
parents:
diff changeset
215
anatofuz
parents:
diff changeset
216 class _LIBCPP_TYPE_VIS thread
anatofuz
parents:
diff changeset
217 {
anatofuz
parents:
diff changeset
218 __libcpp_thread_t __t_;
anatofuz
parents:
diff changeset
219
anatofuz
parents:
diff changeset
220 thread(const thread&);
anatofuz
parents:
diff changeset
221 thread& operator=(const thread&);
anatofuz
parents:
diff changeset
222 public:
anatofuz
parents:
diff changeset
223 typedef __thread_id id;
anatofuz
parents:
diff changeset
224 typedef __libcpp_thread_t native_handle_type;
anatofuz
parents:
diff changeset
225
anatofuz
parents:
diff changeset
226 _LIBCPP_INLINE_VISIBILITY
anatofuz
parents:
diff changeset
227 thread() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) {}
anatofuz
parents:
diff changeset
228 #ifndef _LIBCPP_CXX03_LANG
anatofuz
parents:
diff changeset
229 template <class _Fp, class ..._Args,
anatofuz
parents:
diff changeset
230 class = typename enable_if
anatofuz
parents:
diff changeset
231 <
anatofuz
parents:
diff changeset
232 !is_same<typename __uncvref<_Fp>::type, thread>::value
anatofuz
parents:
diff changeset
233 >::type
anatofuz
parents:
diff changeset
234 >
anatofuz
parents:
diff changeset
235 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
anatofuz
parents:
diff changeset
236 explicit thread(_Fp&& __f, _Args&&... __args);
anatofuz
parents:
diff changeset
237 #else // _LIBCPP_CXX03_LANG
anatofuz
parents:
diff changeset
238 template <class _Fp>
anatofuz
parents:
diff changeset
239 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
anatofuz
parents:
diff changeset
240 explicit thread(_Fp __f);
anatofuz
parents:
diff changeset
241 #endif
anatofuz
parents:
diff changeset
242 ~thread();
anatofuz
parents:
diff changeset
243
anatofuz
parents:
diff changeset
244 #ifndef _LIBCPP_CXX03_LANG
anatofuz
parents:
diff changeset
245 _LIBCPP_INLINE_VISIBILITY
anatofuz
parents:
diff changeset
246 thread(thread&& __t) _NOEXCEPT : __t_(__t.__t_) {__t.__t_ = _LIBCPP_NULL_THREAD;}
anatofuz
parents:
diff changeset
247 _LIBCPP_INLINE_VISIBILITY
anatofuz
parents:
diff changeset
248 thread& operator=(thread&& __t) _NOEXCEPT;
anatofuz
parents:
diff changeset
249 #endif // _LIBCPP_CXX03_LANG
anatofuz
parents:
diff changeset
250
anatofuz
parents:
diff changeset
251 _LIBCPP_INLINE_VISIBILITY
anatofuz
parents:
diff changeset
252 void swap(thread& __t) _NOEXCEPT {_VSTD::swap(__t_, __t.__t_);}
anatofuz
parents:
diff changeset
253
anatofuz
parents:
diff changeset
254 _LIBCPP_INLINE_VISIBILITY
anatofuz
parents:
diff changeset
255 bool joinable() const _NOEXCEPT {return !__libcpp_thread_isnull(&__t_);}
anatofuz
parents:
diff changeset
256 void join();
anatofuz
parents:
diff changeset
257 void detach();
anatofuz
parents:
diff changeset
258 _LIBCPP_INLINE_VISIBILITY
anatofuz
parents:
diff changeset
259 id get_id() const _NOEXCEPT {return __libcpp_thread_get_id(&__t_);}
anatofuz
parents:
diff changeset
260 _LIBCPP_INLINE_VISIBILITY
anatofuz
parents:
diff changeset
261 native_handle_type native_handle() _NOEXCEPT {return __t_;}
anatofuz
parents:
diff changeset
262
anatofuz
parents:
diff changeset
263 static unsigned hardware_concurrency() _NOEXCEPT;
anatofuz
parents:
diff changeset
264 };
anatofuz
parents:
diff changeset
265
anatofuz
parents:
diff changeset
266 #ifndef _LIBCPP_CXX03_LANG
anatofuz
parents:
diff changeset
267
anatofuz
parents:
diff changeset
268 template <class _TSp, class _Fp, class ..._Args, size_t ..._Indices>
anatofuz
parents:
diff changeset
269 inline _LIBCPP_INLINE_VISIBILITY
anatofuz
parents:
diff changeset
270 void
anatofuz
parents:
diff changeset
271 __thread_execute(tuple<_TSp, _Fp, _Args...>& __t, __tuple_indices<_Indices...>)
anatofuz
parents:
diff changeset
272 {
anatofuz
parents:
diff changeset
273 __invoke(_VSTD::move(_VSTD::get<1>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...);
anatofuz
parents:
diff changeset
274 }
anatofuz
parents:
diff changeset
275
anatofuz
parents:
diff changeset
276 template <class _Fp>
anatofuz
parents:
diff changeset
277 _LIBCPP_INLINE_VISIBILITY
anatofuz
parents:
diff changeset
278 void* __thread_proxy(void* __vp)
anatofuz
parents:
diff changeset
279 {
anatofuz
parents:
diff changeset
280 // _Fp = std::tuple< unique_ptr<__thread_struct>, Functor, Args...>
anatofuz
parents:
diff changeset
281 std::unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp));
anatofuz
parents:
diff changeset
282 __thread_local_data().set_pointer(_VSTD::get<0>(*__p).release());
anatofuz
parents:
diff changeset
283 typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 2>::type _Index;
anatofuz
parents:
diff changeset
284 __thread_execute(*__p, _Index());
anatofuz
parents:
diff changeset
285 return nullptr;
anatofuz
parents:
diff changeset
286 }
anatofuz
parents:
diff changeset
287
anatofuz
parents:
diff changeset
288 template <class _Fp, class ..._Args,
anatofuz
parents:
diff changeset
289 class
anatofuz
parents:
diff changeset
290 >
anatofuz
parents:
diff changeset
291 thread::thread(_Fp&& __f, _Args&&... __args)
anatofuz
parents:
diff changeset
292 {
anatofuz
parents:
diff changeset
293 typedef unique_ptr<__thread_struct> _TSPtr;
anatofuz
parents:
diff changeset
294 _TSPtr __tsp(new __thread_struct);
anatofuz
parents:
diff changeset
295 typedef tuple<_TSPtr, typename decay<_Fp>::type, typename decay<_Args>::type...> _Gp;
anatofuz
parents:
diff changeset
296 _VSTD::unique_ptr<_Gp> __p(
anatofuz
parents:
diff changeset
297 new _Gp(std::move(__tsp),
anatofuz
parents:
diff changeset
298 __decay_copy(_VSTD::forward<_Fp>(__f)),
anatofuz
parents:
diff changeset
299 __decay_copy(_VSTD::forward<_Args>(__args))...));
anatofuz
parents:
diff changeset
300 int __ec = __libcpp_thread_create(&__t_, &__thread_proxy<_Gp>, __p.get());
anatofuz
parents:
diff changeset
301 if (__ec == 0)
anatofuz
parents:
diff changeset
302 __p.release();
anatofuz
parents:
diff changeset
303 else
anatofuz
parents:
diff changeset
304 __throw_system_error(__ec, "thread constructor failed");
anatofuz
parents:
diff changeset
305 }
anatofuz
parents:
diff changeset
306
anatofuz
parents:
diff changeset
307 inline
anatofuz
parents:
diff changeset
308 thread&
anatofuz
parents:
diff changeset
309 thread::operator=(thread&& __t) _NOEXCEPT
anatofuz
parents:
diff changeset
310 {
anatofuz
parents:
diff changeset
311 if (!__libcpp_thread_isnull(&__t_))
anatofuz
parents:
diff changeset
312 terminate();
anatofuz
parents:
diff changeset
313 __t_ = __t.__t_;
anatofuz
parents:
diff changeset
314 __t.__t_ = _LIBCPP_NULL_THREAD;
anatofuz
parents:
diff changeset
315 return *this;
anatofuz
parents:
diff changeset
316 }
anatofuz
parents:
diff changeset
317
anatofuz
parents:
diff changeset
318 #else // _LIBCPP_CXX03_LANG
anatofuz
parents:
diff changeset
319
anatofuz
parents:
diff changeset
320 template <class _Fp>
anatofuz
parents:
diff changeset
321 struct __thread_invoke_pair {
anatofuz
parents:
diff changeset
322 // This type is used to pass memory for thread local storage and a functor
anatofuz
parents:
diff changeset
323 // to a newly created thread because std::pair doesn't work with
anatofuz
parents:
diff changeset
324 // std::unique_ptr in C++03.
anatofuz
parents:
diff changeset
325 __thread_invoke_pair(_Fp& __f) : __tsp_(new __thread_struct), __fn_(__f) {}
anatofuz
parents:
diff changeset
326 unique_ptr<__thread_struct> __tsp_;
anatofuz
parents:
diff changeset
327 _Fp __fn_;
anatofuz
parents:
diff changeset
328 };
anatofuz
parents:
diff changeset
329
anatofuz
parents:
diff changeset
330 template <class _Fp>
anatofuz
parents:
diff changeset
331 void* __thread_proxy_cxx03(void* __vp)
anatofuz
parents:
diff changeset
332 {
anatofuz
parents:
diff changeset
333 std::unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp));
anatofuz
parents:
diff changeset
334 __thread_local_data().set_pointer(__p->__tsp_.release());
anatofuz
parents:
diff changeset
335 (__p->__fn_)();
anatofuz
parents:
diff changeset
336 return nullptr;
anatofuz
parents:
diff changeset
337 }
anatofuz
parents:
diff changeset
338
anatofuz
parents:
diff changeset
339 template <class _Fp>
anatofuz
parents:
diff changeset
340 thread::thread(_Fp __f)
anatofuz
parents:
diff changeset
341 {
anatofuz
parents:
diff changeset
342
anatofuz
parents:
diff changeset
343 typedef __thread_invoke_pair<_Fp> _InvokePair;
anatofuz
parents:
diff changeset
344 typedef std::unique_ptr<_InvokePair> _PairPtr;
anatofuz
parents:
diff changeset
345 _PairPtr __pp(new _InvokePair(__f));
anatofuz
parents:
diff changeset
346 int __ec = __libcpp_thread_create(&__t_, &__thread_proxy_cxx03<_InvokePair>, __pp.get());
anatofuz
parents:
diff changeset
347 if (__ec == 0)
anatofuz
parents:
diff changeset
348 __pp.release();
anatofuz
parents:
diff changeset
349 else
anatofuz
parents:
diff changeset
350 __throw_system_error(__ec, "thread constructor failed");
anatofuz
parents:
diff changeset
351 }
anatofuz
parents:
diff changeset
352
anatofuz
parents:
diff changeset
353 #endif // _LIBCPP_CXX03_LANG
anatofuz
parents:
diff changeset
354
anatofuz
parents:
diff changeset
355 inline _LIBCPP_INLINE_VISIBILITY
anatofuz
parents:
diff changeset
356 void swap(thread& __x, thread& __y) _NOEXCEPT {__x.swap(__y);}
anatofuz
parents:
diff changeset
357
anatofuz
parents:
diff changeset
358 namespace this_thread
anatofuz
parents:
diff changeset
359 {
anatofuz
parents:
diff changeset
360
anatofuz
parents:
diff changeset
361 _LIBCPP_FUNC_VIS void sleep_for(const chrono::nanoseconds& __ns);
anatofuz
parents:
diff changeset
362
anatofuz
parents:
diff changeset
363 template <class _Rep, class _Period>
anatofuz
parents:
diff changeset
364 void
anatofuz
parents:
diff changeset
365 sleep_for(const chrono::duration<_Rep, _Period>& __d)
anatofuz
parents:
diff changeset
366 {
anatofuz
parents:
diff changeset
367 using namespace chrono;
anatofuz
parents:
diff changeset
368 if (__d > duration<_Rep, _Period>::zero())
anatofuz
parents:
diff changeset
369 {
anatofuz
parents:
diff changeset
370 #if defined(_LIBCPP_COMPILER_GCC) && (__powerpc__ || __POWERPC__)
anatofuz
parents:
diff changeset
371 // GCC's long double const folding is incomplete for IBM128 long doubles.
anatofuz
parents:
diff changeset
372 _LIBCPP_CONSTEXPR duration<long double> _Max = nanoseconds::max();
anatofuz
parents:
diff changeset
373 #else
anatofuz
parents:
diff changeset
374 _LIBCPP_CONSTEXPR duration<long double> _Max = duration<long double>(ULLONG_MAX/1000000000ULL) ;
anatofuz
parents:
diff changeset
375 #endif
anatofuz
parents:
diff changeset
376 nanoseconds __ns;
anatofuz
parents:
diff changeset
377 if (__d < _Max)
anatofuz
parents:
diff changeset
378 {
anatofuz
parents:
diff changeset
379 __ns = duration_cast<nanoseconds>(__d);
anatofuz
parents:
diff changeset
380 if (__ns < __d)
anatofuz
parents:
diff changeset
381 ++__ns;
anatofuz
parents:
diff changeset
382 }
anatofuz
parents:
diff changeset
383 else
anatofuz
parents:
diff changeset
384 __ns = nanoseconds::max();
anatofuz
parents:
diff changeset
385 sleep_for(__ns);
anatofuz
parents:
diff changeset
386 }
anatofuz
parents:
diff changeset
387 }
anatofuz
parents:
diff changeset
388
anatofuz
parents:
diff changeset
389 template <class _Clock, class _Duration>
anatofuz
parents:
diff changeset
390 void
anatofuz
parents:
diff changeset
391 sleep_until(const chrono::time_point<_Clock, _Duration>& __t)
anatofuz
parents:
diff changeset
392 {
anatofuz
parents:
diff changeset
393 using namespace chrono;
anatofuz
parents:
diff changeset
394 mutex __mut;
anatofuz
parents:
diff changeset
395 condition_variable __cv;
anatofuz
parents:
diff changeset
396 unique_lock<mutex> __lk(__mut);
anatofuz
parents:
diff changeset
397 while (_Clock::now() < __t)
anatofuz
parents:
diff changeset
398 __cv.wait_until(__lk, __t);
anatofuz
parents:
diff changeset
399 }
anatofuz
parents:
diff changeset
400
anatofuz
parents:
diff changeset
401 template <class _Duration>
anatofuz
parents:
diff changeset
402 inline _LIBCPP_INLINE_VISIBILITY
anatofuz
parents:
diff changeset
403 void
anatofuz
parents:
diff changeset
404 sleep_until(const chrono::time_point<chrono::steady_clock, _Duration>& __t)
anatofuz
parents:
diff changeset
405 {
anatofuz
parents:
diff changeset
406 using namespace chrono;
anatofuz
parents:
diff changeset
407 sleep_for(__t - steady_clock::now());
anatofuz
parents:
diff changeset
408 }
anatofuz
parents:
diff changeset
409
anatofuz
parents:
diff changeset
410 inline _LIBCPP_INLINE_VISIBILITY
anatofuz
parents:
diff changeset
411 void yield() _NOEXCEPT {__libcpp_thread_yield();}
anatofuz
parents:
diff changeset
412
anatofuz
parents:
diff changeset
413 } // this_thread
anatofuz
parents:
diff changeset
414
anatofuz
parents:
diff changeset
415 _LIBCPP_END_NAMESPACE_STD
anatofuz
parents:
diff changeset
416
anatofuz
parents:
diff changeset
417 #endif // !_LIBCPP_HAS_NO_THREADS
anatofuz
parents:
diff changeset
418
anatofuz
parents:
diff changeset
419 _LIBCPP_POP_MACROS
anatofuz
parents:
diff changeset
420
anatofuz
parents:
diff changeset
421 #endif // _LIBCPP_THREAD