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