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