Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef _GLIBCXX_THREAD
00030 #define _GLIBCXX_THREAD 1
00031
00032 #pragma GCC system_header
00033
00034 #ifndef __GXX_EXPERIMENTAL_CXX0X__
00035 # include <bits/c++0x_warning.h>
00036 #else
00037
00038 #include <chrono>
00039 #include <functional>
00040 #include <memory>
00041 #include <mutex>
00042 #include <condition_variable>
00043 #include <bits/functexcept.h>
00044 #include <bits/functional_hash.h>
00045 #include <bits/gthr.h>
00046
00047 #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1)
00048
00049 namespace std
00050 {
00051
00052
00053
00054
00055
00056
00057
00058
00059 template<typename _Tp>
00060 struct hash;
00061
00062
00063 class thread
00064 {
00065 public:
00066 typedef __gthread_t native_handle_type;
00067 struct _Impl_base;
00068 typedef shared_ptr<_Impl_base> __shared_base_type;
00069
00070
00071 class id
00072 {
00073 native_handle_type _M_thread;
00074
00075 public:
00076 id() : _M_thread() { }
00077
00078 explicit
00079 id(native_handle_type __id) : _M_thread(__id) { }
00080
00081 private:
00082 friend class thread;
00083 friend class hash<thread::id>;
00084
00085 friend bool
00086 operator==(thread::id __x, thread::id __y)
00087 { return __gthread_equal(__x._M_thread, __y._M_thread); }
00088
00089 friend bool
00090 operator<(thread::id __x, thread::id __y)
00091 { return __x._M_thread < __y._M_thread; }
00092
00093 template<class _CharT, class _Traits>
00094 friend basic_ostream<_CharT, _Traits>&
00095 operator<<(basic_ostream<_CharT, _Traits>& __out, thread::id __id);
00096 };
00097
00098
00099
00100 struct _Impl_base
00101 {
00102 __shared_base_type _M_this_ptr;
00103
00104 inline virtual ~_Impl_base();
00105
00106 virtual void _M_run() = 0;
00107 };
00108
00109 template<typename _Callable>
00110 struct _Impl : public _Impl_base
00111 {
00112 _Callable _M_func;
00113
00114 _Impl(_Callable&& __f) : _M_func(std::forward<_Callable>(__f))
00115 { }
00116
00117 void
00118 _M_run() { _M_func(); }
00119 };
00120
00121 private:
00122 id _M_id;
00123
00124 public:
00125 thread() = default;
00126 thread(const thread&) = delete;
00127
00128 thread(thread&& __t)
00129 { swap(__t); }
00130
00131 template<typename _Callable>
00132 explicit thread(_Callable __f)
00133 {
00134 _M_start_thread(_M_make_routine<_Callable>
00135 (std::forward<_Callable>(__f)));
00136 }
00137
00138 template<typename _Callable, typename... _Args>
00139 thread(_Callable&& __f, _Args&&... __args)
00140 { _M_start_thread(_M_make_routine(std::bind(__f, __args...))); }
00141
00142 ~thread()
00143 {
00144 if (joinable())
00145 std::terminate();
00146 }
00147
00148 thread& operator=(const thread&) = delete;
00149
00150 thread& operator=(thread&& __t)
00151 {
00152 if (joinable())
00153 std::terminate();
00154 swap(__t);
00155 return *this;
00156 }
00157
00158 void
00159 swap(thread& __t)
00160 { std::swap(_M_id, __t._M_id); }
00161
00162 bool
00163 joinable() const
00164 { return !(_M_id == id()); }
00165
00166 void
00167 join();
00168
00169 void
00170 detach();
00171
00172 thread::id
00173 get_id() const
00174 { return _M_id; }
00175
00176
00177
00178 native_handle_type
00179 native_handle()
00180 { return _M_id._M_thread; }
00181
00182
00183 static unsigned int
00184 hardware_concurrency()
00185 { return 0; }
00186
00187 private:
00188 void
00189 _M_start_thread(__shared_base_type);
00190
00191 template<typename _Callable>
00192 shared_ptr<_Impl<_Callable>>
00193 _M_make_routine(_Callable&& __f)
00194 {
00195
00196 return make_shared<_Impl<_Callable>>(std::forward<_Callable>(__f));
00197 }
00198 };
00199
00200 inline thread::_Impl_base::~_Impl_base() = default;
00201
00202 inline void
00203 swap(thread& __x, thread& __y)
00204 { __x.swap(__y); }
00205
00206 inline bool
00207 operator!=(thread::id __x, thread::id __y)
00208 { return !(__x == __y); }
00209
00210 inline bool
00211 operator<=(thread::id __x, thread::id __y)
00212 { return !(__y < __x); }
00213
00214 inline bool
00215 operator>(thread::id __x, thread::id __y)
00216 { return __y < __x; }
00217
00218 inline bool
00219 operator>=(thread::id __x, thread::id __y)
00220 { return !(__x < __y); }
00221
00222
00223
00224 template<>
00225 struct hash<thread::id>
00226 : public std::unary_function<thread::id, size_t>
00227 {
00228 size_t
00229 operator()(const thread::id& __id) const
00230 { return std::_Fnv_hash::hash(__id._M_thread); }
00231 };
00232
00233 template<class _CharT, class _Traits>
00234 inline basic_ostream<_CharT, _Traits>&
00235 operator<<(basic_ostream<_CharT, _Traits>& __out, thread::id __id)
00236 {
00237 if (__id == thread::id())
00238 return __out << "thread::id of a non-executing thread";
00239 else
00240 return __out << __id._M_thread;
00241 }
00242
00243
00244
00245
00246
00247 namespace this_thread
00248 {
00249
00250 inline thread::id
00251 get_id() { return thread::id(__gthread_self()); }
00252
00253 #ifdef _GLIBCXX_USE_SCHED_YIELD
00254
00255 inline void
00256 yield()
00257 { __gthread_yield(); }
00258 #endif
00259
00260 #ifdef _GLIBCXX_USE_NANOSLEEP
00261
00262 template<typename _Clock, typename _Duration>
00263 inline void
00264 sleep_until(const chrono::time_point<_Clock, _Duration>& __atime)
00265 { sleep_for(__atime - _Clock::now()); }
00266
00267
00268 template<typename _Rep, typename _Period>
00269 inline void
00270 sleep_for(const chrono::duration<_Rep, _Period>& __rtime)
00271 {
00272 chrono::seconds __s =
00273 chrono::duration_cast<chrono::seconds>(__rtime);
00274
00275 chrono::nanoseconds __ns =
00276 chrono::duration_cast<chrono::nanoseconds>(__rtime - __s);
00277
00278 __gthread_time_t __ts =
00279 {
00280 static_cast<std::time_t>(__s.count()),
00281 static_cast<long>(__ns.count())
00282 };
00283
00284 ::nanosleep(&__ts, 0);
00285 }
00286 #endif
00287 }
00288
00289
00290 }
00291
00292 #endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1
00293
00294 #endif // __GXX_EXPERIMENTAL_CXX0X__
00295
00296 #endif // _GLIBCXX_THREAD