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