| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 1 | // -*- C++ -*- | 
 | 2 | //===--------------------------- thread -----------------------------------===// | 
 | 3 | // | 
| Howard Hinnant | f5256e1 | 2010-05-11 21:36:01 +0000 | [diff] [blame] | 4 | //                     The LLVM Compiler Infrastructure | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 5 | // | 
 | 6 | // This file is distributed under the University of Illinois Open Source | 
 | 7 | // License. See LICENSE.TXT for details. | 
 | 8 | // | 
 | 9 | //===----------------------------------------------------------------------===// | 
 | 10 |  | 
 | 11 | #ifndef _LIBCPP_THREAD | 
 | 12 | #define _LIBCPP_THREAD | 
 | 13 |  | 
 | 14 | /* | 
 | 15 |  | 
 | 16 |     thread synopsis | 
 | 17 |  | 
| Howard Hinnant | a785e4e | 2010-08-21 21:01:59 +0000 | [diff] [blame] | 18 | #define __STDCPP_THREADS__ __cplusplus | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 19 |  | 
 | 20 | namespace std | 
 | 21 | { | 
 | 22 |  | 
 | 23 | class thread | 
 | 24 | { | 
 | 25 | public: | 
 | 26 |     class id; | 
 | 27 |     typedef pthread_t native_handle_type; | 
 | 28 |  | 
 | 29 |     thread(); | 
 | 30 |     template <class F, class ...Args> explicit thread(F&& f, Args&&... args); | 
 | 31 |     ~thread(); | 
 | 32 |  | 
 | 33 |     thread(const thread&) = delete; | 
 | 34 |     thread(thread&& t); | 
 | 35 |  | 
 | 36 |     thread& operator=(const thread&) = delete; | 
 | 37 |     thread& operator=(thread&& t); | 
 | 38 |  | 
 | 39 |     void swap(thread& t); | 
 | 40 |  | 
 | 41 |     bool joinable() const; | 
 | 42 |     void join(); | 
 | 43 |     void detach(); | 
 | 44 |     id get_id() const; | 
 | 45 |     native_handle_type native_handle(); | 
 | 46 |  | 
 | 47 |     static unsigned hardware_concurrency(); | 
 | 48 | }; | 
 | 49 |  | 
 | 50 | void swap(thread& x, thread& y); | 
 | 51 |  | 
 | 52 | class thread::id | 
 | 53 | { | 
 | 54 | public: | 
 | 55 |     id(); | 
 | 56 | }; | 
 | 57 |  | 
 | 58 | bool operator==(thread::id x, thread::id y); | 
 | 59 | bool operator!=(thread::id x, thread::id y); | 
 | 60 | bool operator< (thread::id x, thread::id y); | 
 | 61 | bool operator<=(thread::id x, thread::id y); | 
 | 62 | bool operator> (thread::id x, thread::id y); | 
 | 63 | bool operator>=(thread::id x, thread::id y); | 
 | 64 |  | 
 | 65 | template<class charT, class traits> | 
 | 66 | basic_ostream<charT, traits>& | 
 | 67 | operator<<(basic_ostream<charT, traits>& out, thread::id id); | 
 | 68 |  | 
 | 69 | namespace this_thread | 
 | 70 | { | 
 | 71 |  | 
 | 72 | thread::id get_id(); | 
 | 73 |  | 
 | 74 | void yield(); | 
 | 75 |  | 
 | 76 | template <class Clock, class Duration> | 
 | 77 | void sleep_until(const chrono::time_point<Clock, Duration>& abs_time); | 
 | 78 |  | 
 | 79 | template <class Rep, class Period> | 
 | 80 | void sleep_for(const chrono::duration<Rep, Period>& rel_time); | 
 | 81 |  | 
 | 82 | }  // this_thread | 
 | 83 |  | 
 | 84 | }  // std | 
 | 85 |  | 
 | 86 | */ | 
 | 87 |  | 
 | 88 | #include <__config> | 
 | 89 | #include <iosfwd> | 
 | 90 | #include <__functional_base> | 
 | 91 | #include <type_traits> | 
 | 92 | #include <cstddef> | 
 | 93 | #include <functional> | 
 | 94 | #include <memory> | 
 | 95 | #include <system_error> | 
 | 96 | #include <chrono> | 
 | 97 | #include <__mutex_base> | 
 | 98 | #include <pthread.h> | 
 | 99 |  | 
 | 100 | #pragma GCC system_header | 
 | 101 |  | 
| Howard Hinnant | a785e4e | 2010-08-21 21:01:59 +0000 | [diff] [blame] | 102 | #define __STDCPP_THREADS__ __cplusplus | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 103 |  | 
 | 104 | _LIBCPP_BEGIN_NAMESPACE_STD | 
 | 105 |  | 
| Howard Hinnant | 47499b1 | 2010-08-27 20:10:19 +0000 | [diff] [blame] | 106 | template <class _Tp> | 
 | 107 | class __thread_specific_ptr | 
 | 108 | { | 
 | 109 |     pthread_key_t __key_; | 
 | 110 |  | 
 | 111 |     __thread_specific_ptr(const __thread_specific_ptr&); | 
 | 112 |     __thread_specific_ptr& operator=(const __thread_specific_ptr&); | 
 | 113 |  | 
 | 114 |     static void __at_thread_exit(void*); | 
 | 115 | public: | 
 | 116 |     typedef _Tp* pointer; | 
 | 117 |  | 
 | 118 |     __thread_specific_ptr(); | 
 | 119 |     ~__thread_specific_ptr(); | 
 | 120 |  | 
| Howard Hinnant | 8d7a955 | 2010-09-23 17:31:07 +0000 | [diff] [blame] | 121 |     _LIBCPP_INLINE_VISIBILITY | 
| Howard Hinnant | 47499b1 | 2010-08-27 20:10:19 +0000 | [diff] [blame] | 122 |     pointer get() const {return static_cast<_Tp*>(pthread_getspecific(__key_));} | 
| Howard Hinnant | 8d7a955 | 2010-09-23 17:31:07 +0000 | [diff] [blame] | 123 |     _LIBCPP_INLINE_VISIBILITY | 
| Howard Hinnant | 47499b1 | 2010-08-27 20:10:19 +0000 | [diff] [blame] | 124 |     pointer operator*() const {return *get();} | 
| Howard Hinnant | 8d7a955 | 2010-09-23 17:31:07 +0000 | [diff] [blame] | 125 |     _LIBCPP_INLINE_VISIBILITY | 
| Howard Hinnant | 47499b1 | 2010-08-27 20:10:19 +0000 | [diff] [blame] | 126 |     pointer operator->() const {return get();} | 
 | 127 |     pointer release(); | 
 | 128 |     void reset(pointer __p = nullptr); | 
 | 129 | }; | 
 | 130 |  | 
 | 131 | template <class _Tp> | 
 | 132 | void | 
 | 133 | __thread_specific_ptr<_Tp>::__at_thread_exit(void* __p) | 
 | 134 | { | 
 | 135 | 	delete static_cast<pointer>(__p); | 
 | 136 | } | 
 | 137 |  | 
 | 138 | template <class _Tp> | 
 | 139 | __thread_specific_ptr<_Tp>::__thread_specific_ptr() | 
 | 140 | { | 
 | 141 |     int __ec = pthread_key_create(&__key_, &__thread_specific_ptr::__at_thread_exit); | 
 | 142 | 	if (__ec) | 
 | 143 | 		throw system_error(error_code(__ec, system_category()), | 
 | 144 | 		                   "__thread_specific_ptr construction failed"); | 
 | 145 | } | 
 | 146 |  | 
 | 147 | template <class _Tp> | 
 | 148 | __thread_specific_ptr<_Tp>::~__thread_specific_ptr() | 
 | 149 | { | 
 | 150 | 	pthread_key_delete(__key_); | 
 | 151 | } | 
 | 152 |  | 
 | 153 | template <class _Tp> | 
 | 154 | typename __thread_specific_ptr<_Tp>::pointer | 
 | 155 | __thread_specific_ptr<_Tp>::release() | 
 | 156 | { | 
 | 157 | 	pointer __p = get(); | 
 | 158 | 	pthread_setspecific(__key_, 0); | 
 | 159 | 	return __p; | 
 | 160 | } | 
 | 161 |  | 
 | 162 | template <class _Tp> | 
 | 163 | void | 
 | 164 | __thread_specific_ptr<_Tp>::reset(pointer __p) | 
 | 165 | { | 
 | 166 | 	pointer __p_old = get(); | 
 | 167 | 	pthread_setspecific(__key_, __p); | 
 | 168 | 	delete __p_old; | 
 | 169 | } | 
 | 170 |  | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 171 | class thread; | 
 | 172 | class __thread_id; | 
 | 173 |  | 
 | 174 | namespace this_thread | 
 | 175 | { | 
 | 176 |  | 
 | 177 | __thread_id get_id(); | 
 | 178 |  | 
 | 179 | }  // this_thread | 
 | 180 |  | 
| Howard Hinnant | 8d7a955 | 2010-09-23 17:31:07 +0000 | [diff] [blame] | 181 | class _LIBCPP_VISIBLE __thread_id | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 182 | { | 
| Howard Hinnant | adff489 | 2010-05-24 17:49:41 +0000 | [diff] [blame] | 183 |     // FIXME: pthread_t is a pointer on Darwin but a long on Linux. | 
 | 184 |     // NULL is the no-thread value on Darwin.  Someone needs to check | 
 | 185 |     // on other platforms.  We assume 0 works everywhere for now. | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 186 |     pthread_t __id_; | 
 | 187 |  | 
 | 188 | public: | 
| Howard Hinnant | 8d7a955 | 2010-09-23 17:31:07 +0000 | [diff] [blame] | 189 |     _LIBCPP_INLINE_VISIBILITY | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 190 |     __thread_id() : __id_(0) {} | 
 | 191 |  | 
| Howard Hinnant | 8d7a955 | 2010-09-23 17:31:07 +0000 | [diff] [blame] | 192 |     friend _LIBCPP_INLINE_VISIBILITY | 
 | 193 |         bool operator==(__thread_id __x, __thread_id __y) | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 194 |         {return __x.__id_ == __y.__id_;} | 
| Howard Hinnant | 8d7a955 | 2010-09-23 17:31:07 +0000 | [diff] [blame] | 195 |     friend _LIBCPP_INLINE_VISIBILITY | 
 | 196 |         bool operator!=(__thread_id __x, __thread_id __y) | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 197 |         {return !(__x == __y);} | 
| Howard Hinnant | 8d7a955 | 2010-09-23 17:31:07 +0000 | [diff] [blame] | 198 |     friend _LIBCPP_INLINE_VISIBILITY | 
 | 199 |         bool operator< (__thread_id __x, __thread_id __y) | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 200 |         {return __x.__id_ < __y.__id_;} | 
| Howard Hinnant | 8d7a955 | 2010-09-23 17:31:07 +0000 | [diff] [blame] | 201 |     friend _LIBCPP_INLINE_VISIBILITY | 
 | 202 |         bool operator<=(__thread_id __x, __thread_id __y) | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 203 |         {return !(__y < __x);} | 
| Howard Hinnant | 8d7a955 | 2010-09-23 17:31:07 +0000 | [diff] [blame] | 204 |     friend _LIBCPP_INLINE_VISIBILITY | 
 | 205 |         bool operator> (__thread_id __x, __thread_id __y) | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 206 |         {return   __y < __x ;} | 
| Howard Hinnant | 8d7a955 | 2010-09-23 17:31:07 +0000 | [diff] [blame] | 207 |     friend _LIBCPP_INLINE_VISIBILITY | 
 | 208 |         bool operator>=(__thread_id __x, __thread_id __y) | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 209 |         {return !(__x < __y);} | 
 | 210 |  | 
 | 211 |     template<class _CharT, class _Traits> | 
 | 212 |     friend | 
| Howard Hinnant | 8d7a955 | 2010-09-23 17:31:07 +0000 | [diff] [blame] | 213 |     _LIBCPP_INLINE_VISIBILITY | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 214 |     basic_ostream<_CharT, _Traits>& | 
 | 215 |     operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id) | 
 | 216 |         {return __os << __id.__id_;} | 
 | 217 |  | 
 | 218 | private: | 
| Howard Hinnant | 8d7a955 | 2010-09-23 17:31:07 +0000 | [diff] [blame] | 219 |     _LIBCPP_INLINE_VISIBILITY | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 220 |     __thread_id(pthread_t __id) : __id_(__id) {} | 
 | 221 |  | 
 | 222 |     friend __thread_id this_thread::get_id(); | 
| Howard Hinnant | 8d7a955 | 2010-09-23 17:31:07 +0000 | [diff] [blame] | 223 |     friend class _LIBCPP_VISIBLE thread; | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 224 | }; | 
 | 225 |  | 
 | 226 | template<class _Tp> struct hash; | 
 | 227 |  | 
 | 228 | template<> | 
| Howard Hinnant | 8d7a955 | 2010-09-23 17:31:07 +0000 | [diff] [blame] | 229 | struct _LIBCPP_VISIBLE hash<__thread_id> | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 230 |     : public unary_function<__thread_id, size_t> | 
 | 231 | { | 
| Howard Hinnant | 8d7a955 | 2010-09-23 17:31:07 +0000 | [diff] [blame] | 232 |     _LIBCPP_INLINE_VISIBILITY | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 233 |     size_t operator()(__thread_id __v) const | 
 | 234 |     { | 
 | 235 |         const size_t* const __p = reinterpret_cast<const size_t*>(&__v); | 
 | 236 |         return *__p; | 
 | 237 |     } | 
 | 238 | }; | 
 | 239 |  | 
 | 240 | namespace this_thread | 
 | 241 | { | 
 | 242 |  | 
| Howard Hinnant | 8d7a955 | 2010-09-23 17:31:07 +0000 | [diff] [blame] | 243 | inline _LIBCPP_INLINE_VISIBILITY | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 244 | __thread_id | 
 | 245 | get_id() | 
 | 246 | { | 
 | 247 |     return pthread_self(); | 
 | 248 | } | 
 | 249 |  | 
 | 250 | }  // this_thread | 
 | 251 |  | 
| Howard Hinnant | 8d7a955 | 2010-09-23 17:31:07 +0000 | [diff] [blame] | 252 | class _LIBCPP_VISIBLE thread | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 253 | { | 
 | 254 |     pthread_t __t_; | 
 | 255 |  | 
| Howard Hinnant | 60a0a8e | 2010-08-10 20:48:29 +0000 | [diff] [blame] | 256 |     thread(const thread&); | 
 | 257 |     thread& operator=(const thread&); | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 258 | public: | 
 | 259 |     typedef __thread_id id; | 
 | 260 |     typedef pthread_t native_handle_type; | 
 | 261 |  | 
| Howard Hinnant | 8d7a955 | 2010-09-23 17:31:07 +0000 | [diff] [blame] | 262 |     _LIBCPP_INLINE_VISIBILITY | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 263 |     thread() : __t_(0) {} | 
 | 264 | #ifndef _LIBCPP_HAS_NO_VARIADICS | 
 | 265 |     template <class _F, class ..._Args, | 
 | 266 |               class = typename enable_if | 
 | 267 |               < | 
 | 268 |                    !is_same<typename decay<_F>::type, thread>::value | 
 | 269 |               >::type | 
 | 270 |              > | 
 | 271 |         explicit thread(_F&& __f, _Args&&... __args); | 
| Howard Hinnant | 324bb03 | 2010-08-22 00:02:43 +0000 | [diff] [blame] | 272 | #else  // _LIBCPP_HAS_NO_VARIADICS | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 273 |     template <class _F> explicit thread(_F __f); | 
 | 274 | #endif | 
 | 275 |     ~thread(); | 
 | 276 |  | 
| Howard Hinnant | 73d21a4 | 2010-09-04 23:28:19 +0000 | [diff] [blame] | 277 | #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES | 
| Howard Hinnant | 8d7a955 | 2010-09-23 17:31:07 +0000 | [diff] [blame] | 278 |     _LIBCPP_INLINE_VISIBILITY | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 279 |     thread(thread&& __t) : __t_(__t.__t_) {__t.__t_ = 0;} | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 280 |     thread& operator=(thread&& __t); | 
| Howard Hinnant | 73d21a4 | 2010-09-04 23:28:19 +0000 | [diff] [blame] | 281 | #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 282 |  | 
| Howard Hinnant | 8d7a955 | 2010-09-23 17:31:07 +0000 | [diff] [blame] | 283 |     _LIBCPP_INLINE_VISIBILITY | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 284 |     void swap(thread& __t) {_STD::swap(__t_, __t.__t_);} | 
 | 285 |  | 
| Howard Hinnant | 8d7a955 | 2010-09-23 17:31:07 +0000 | [diff] [blame] | 286 |     _LIBCPP_INLINE_VISIBILITY | 
| Howard Hinnant | adff489 | 2010-05-24 17:49:41 +0000 | [diff] [blame] | 287 |     bool joinable() const {return __t_ != 0;} | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 288 |     void join(); | 
 | 289 |     void detach(); | 
| Howard Hinnant | 8d7a955 | 2010-09-23 17:31:07 +0000 | [diff] [blame] | 290 |     _LIBCPP_INLINE_VISIBILITY | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 291 |     id get_id() const {return __t_;} | 
| Howard Hinnant | 8d7a955 | 2010-09-23 17:31:07 +0000 | [diff] [blame] | 292 |     _LIBCPP_INLINE_VISIBILITY | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 293 |     native_handle_type native_handle() {return __t_;} | 
 | 294 |  | 
 | 295 |     static unsigned hardware_concurrency(); | 
 | 296 | }; | 
 | 297 |  | 
| Howard Hinnant | 47499b1 | 2010-08-27 20:10:19 +0000 | [diff] [blame] | 298 | class __assoc_sub_state; | 
 | 299 |  | 
 | 300 | class __thread_struct_imp; | 
 | 301 |  | 
 | 302 | class __thread_struct | 
 | 303 | { | 
 | 304 |     __thread_struct_imp* __p_; | 
 | 305 |  | 
 | 306 |     __thread_struct(const __thread_struct&); | 
 | 307 |     __thread_struct& operator=(const __thread_struct&); | 
 | 308 | public: | 
 | 309 |     __thread_struct(); | 
 | 310 |     ~__thread_struct(); | 
 | 311 |  | 
| Howard Hinnant | e6e4d01 | 2010-09-03 21:46:37 +0000 | [diff] [blame] | 312 |     void notify_all_at_thread_exit(condition_variable*, mutex*); | 
| Howard Hinnant | 47499b1 | 2010-08-27 20:10:19 +0000 | [diff] [blame] | 313 |     void __make_ready_at_thread_exit(__assoc_sub_state*); | 
 | 314 | }; | 
 | 315 |  | 
| Howard Hinnant | 5306d68 | 2010-10-14 19:18:04 +0000 | [diff] [blame] | 316 | __thread_specific_ptr<__thread_struct>& __thread_local_data(); | 
| Howard Hinnant | 47499b1 | 2010-08-27 20:10:19 +0000 | [diff] [blame] | 317 |  | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 318 | template <class _F> | 
 | 319 | void* | 
 | 320 | __thread_proxy(void* __vp) | 
 | 321 | { | 
| Howard Hinnant | 5306d68 | 2010-10-14 19:18:04 +0000 | [diff] [blame] | 322 |     __thread_local_data().reset(new __thread_struct); | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 323 |     std::unique_ptr<_F> __p(static_cast<_F*>(__vp)); | 
 | 324 |     (*__p)(); | 
 | 325 |     return nullptr; | 
 | 326 | } | 
 | 327 |  | 
 | 328 | #ifndef _LIBCPP_HAS_NO_VARIADICS | 
 | 329 |  | 
 | 330 | template <class _F, class ..._Args, | 
 | 331 |           class | 
 | 332 |          > | 
 | 333 | thread::thread(_F&& __f, _Args&&... __args) | 
 | 334 | { | 
 | 335 |     typedef decltype(bind(std::forward<_F>(__f), std::forward<_Args>(__args)...)) _G; | 
 | 336 |     std::unique_ptr<_G> __p(new _G(bind(std::forward<_F>(__f), | 
 | 337 |                               std::forward<_Args>(__args)...))); | 
 | 338 |     int __ec = pthread_create(&__t_, 0, &__thread_proxy<_G>, __p.get()); | 
 | 339 |     if (__ec == 0) | 
 | 340 |         __p.release(); | 
 | 341 |     else | 
 | 342 |         __throw_system_error(__ec, "thread constructor failed"); | 
 | 343 | } | 
 | 344 |  | 
| Howard Hinnant | 324bb03 | 2010-08-22 00:02:43 +0000 | [diff] [blame] | 345 | #else  // _LIBCPP_HAS_NO_VARIADICS | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 346 |  | 
 | 347 | template <class _F> | 
 | 348 | thread::thread(_F __f) | 
 | 349 | { | 
 | 350 |     std::unique_ptr<_F> __p(new _F(__f)); | 
 | 351 |     int __ec = pthread_create(&__t_, 0, &__thread_proxy<_F>, __p.get()); | 
 | 352 |     if (__ec == 0) | 
 | 353 |         __p.release(); | 
 | 354 |     else | 
 | 355 |         __throw_system_error(__ec, "thread constructor failed"); | 
 | 356 | } | 
 | 357 |  | 
| Howard Hinnant | 324bb03 | 2010-08-22 00:02:43 +0000 | [diff] [blame] | 358 | #endif  // _LIBCPP_HAS_NO_VARIADICS | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 359 |  | 
| Howard Hinnant | 73d21a4 | 2010-09-04 23:28:19 +0000 | [diff] [blame] | 360 | #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 361 |  | 
| Howard Hinnant | 8d7a955 | 2010-09-23 17:31:07 +0000 | [diff] [blame] | 362 | inline _LIBCPP_INLINE_VISIBILITY | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 363 | thread& | 
 | 364 | thread::operator=(thread&& __t) | 
 | 365 | { | 
| Howard Hinnant | a6a062d | 2010-06-02 18:20:39 +0000 | [diff] [blame] | 366 |     if (__t_ != 0) | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 367 |         terminate(); | 
 | 368 |     __t_ = __t.__t_; | 
| Howard Hinnant | a6a062d | 2010-06-02 18:20:39 +0000 | [diff] [blame] | 369 |     __t.__t_ = 0; | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 370 |     return *this; | 
 | 371 | } | 
 | 372 |  | 
| Howard Hinnant | 73d21a4 | 2010-09-04 23:28:19 +0000 | [diff] [blame] | 373 | #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 374 |  | 
| Howard Hinnant | 8d7a955 | 2010-09-23 17:31:07 +0000 | [diff] [blame] | 375 | inline _LIBCPP_INLINE_VISIBILITY | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 376 | void swap(thread& __x, thread& __y) {__x.swap(__y);} | 
 | 377 |  | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 378 | namespace this_thread | 
 | 379 | { | 
 | 380 |  | 
 | 381 | void sleep_for(const chrono::nanoseconds& ns); | 
 | 382 |  | 
 | 383 | template <class _Rep, class _Period> | 
 | 384 | void | 
 | 385 | sleep_for(const chrono::duration<_Rep, _Period>& __d) | 
 | 386 | { | 
 | 387 |     using namespace chrono; | 
 | 388 |     nanoseconds __ns = duration_cast<nanoseconds>(__d); | 
 | 389 |     if (__ns < __d) | 
 | 390 |         ++__ns; | 
 | 391 |     sleep_for(__ns); | 
 | 392 | } | 
 | 393 |  | 
 | 394 | template <class _Clock, class _Duration> | 
 | 395 | void | 
 | 396 | sleep_until(const chrono::time_point<_Clock, _Duration>& __t) | 
 | 397 | { | 
 | 398 |     using namespace chrono; | 
 | 399 |     mutex __mut; | 
 | 400 |     condition_variable __cv; | 
 | 401 |     unique_lock<mutex> __lk(__mut); | 
 | 402 |     while (_Clock::now() < __t) | 
 | 403 |         __cv.wait_until(__lk, __t); | 
 | 404 | } | 
 | 405 |  | 
 | 406 | template <class _Duration> | 
| Howard Hinnant | 8d7a955 | 2010-09-23 17:31:07 +0000 | [diff] [blame] | 407 | inline _LIBCPP_INLINE_VISIBILITY | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 408 | void | 
 | 409 | sleep_until(const chrono::time_point<chrono::monotonic_clock, _Duration>& __t) | 
 | 410 | { | 
 | 411 |     using namespace chrono; | 
 | 412 |     sleep_for(__t - monotonic_clock::now()); | 
 | 413 | } | 
 | 414 |  | 
| Howard Hinnant | 8d7a955 | 2010-09-23 17:31:07 +0000 | [diff] [blame] | 415 | inline _LIBCPP_INLINE_VISIBILITY | 
| Howard Hinnant | bc8d3f9 | 2010-05-11 19:42:16 +0000 | [diff] [blame] | 416 | void yield() {sched_yield();} | 
 | 417 |  | 
 | 418 | }  // this_thread | 
 | 419 |  | 
 | 420 | _LIBCPP_END_NAMESPACE_STD | 
 | 421 |  | 
 | 422 | #endif  // _LIBCPP_THREAD |