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