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_CONDITION_VARIABLE
00030 #define _GLIBCXX_CONDITION_VARIABLE 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 <mutex>
00040
00041 #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1)
00042
00043 namespace std
00044 {
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 enum class cv_status { no_timeout, timeout };
00055
00056
00057 class condition_variable
00058 {
00059 typedef chrono::system_clock __clock_t;
00060 typedef __gthread_cond_t __native_type;
00061 __native_type _M_cond;
00062
00063 public:
00064 typedef __native_type* native_handle_type;
00065
00066 condition_variable() throw ();
00067 ~condition_variable() throw ();
00068
00069 condition_variable(const condition_variable&) = delete;
00070 condition_variable& operator=(const condition_variable&) = delete;
00071
00072 void
00073 notify_one();
00074
00075 void
00076 notify_all();
00077
00078 void
00079 wait(unique_lock<mutex>& __lock);
00080
00081 template<typename _Predicate>
00082 void
00083 wait(unique_lock<mutex>& __lock, _Predicate __p)
00084 {
00085 while (!__p())
00086 wait(__lock);
00087 }
00088
00089 template<typename _Duration>
00090 cv_status
00091 wait_until(unique_lock<mutex>& __lock,
00092 const chrono::time_point<__clock_t, _Duration>& __atime)
00093 { return __wait_until_impl(__lock, __atime); }
00094
00095 template<typename _Clock, typename _Duration>
00096 cv_status
00097 wait_until(unique_lock<mutex>& __lock,
00098 const chrono::time_point<_Clock, _Duration>& __atime)
00099 {
00100
00101 const typename _Clock::time_point __c_entry = _Clock::now();
00102 const __clock_t::time_point __s_entry = __clock_t::now();
00103 const chrono::nanoseconds __delta = __atime - __c_entry;
00104 const __clock_t::time_point __s_atime = __s_entry + __delta;
00105
00106 return __wait_until_impl(__lock, __s_atime);
00107 }
00108
00109 template<typename _Clock, typename _Duration, typename _Predicate>
00110 bool
00111 wait_until(unique_lock<mutex>& __lock,
00112 const chrono::time_point<_Clock, _Duration>& __atime,
00113 _Predicate __p)
00114 {
00115 while (!__p())
00116 if (wait_until(__lock, __atime) == cv_status::timeout)
00117 return __p();
00118 return true;
00119 }
00120
00121 template<typename _Rep, typename _Period>
00122 cv_status
00123 wait_for(unique_lock<mutex>& __lock,
00124 const chrono::duration<_Rep, _Period>& __rtime)
00125 { return wait_until(__lock, __clock_t::now() + __rtime); }
00126
00127 template<typename _Rep, typename _Period, typename _Predicate>
00128 bool
00129 wait_for(unique_lock<mutex>& __lock,
00130 const chrono::duration<_Rep, _Period>& __rtime,
00131 _Predicate __p)
00132 { return wait_until(__lock, __clock_t::now() + __rtime, std::move(__p)); }
00133
00134 native_handle_type
00135 native_handle()
00136 { return &_M_cond; }
00137
00138 private:
00139 template<typename _Clock, typename _Duration>
00140 cv_status
00141 __wait_until_impl(unique_lock<mutex>& __lock,
00142 const chrono::time_point<_Clock, _Duration>& __atime)
00143 {
00144 chrono::time_point<__clock_t, chrono::seconds> __s =
00145 chrono::time_point_cast<chrono::seconds>(__atime);
00146
00147 chrono::nanoseconds __ns =
00148 chrono::duration_cast<chrono::nanoseconds>(__atime - __s);
00149
00150 __gthread_time_t __ts =
00151 {
00152 static_cast<std::time_t>(__s.time_since_epoch().count()),
00153 static_cast<long>(__ns.count())
00154 };
00155
00156 __gthread_cond_timedwait(&_M_cond, __lock.mutex()->native_handle(),
00157 &__ts);
00158
00159 return (_Clock::now() < __atime
00160 ? cv_status::no_timeout : cv_status::timeout);
00161 }
00162 };
00163
00164
00165
00166 class condition_variable_any
00167 {
00168 typedef chrono::system_clock __clock_t;
00169 condition_variable _M_cond;
00170 mutex _M_mutex;
00171
00172 public:
00173 typedef condition_variable::native_handle_type native_handle_type;
00174
00175 condition_variable_any() throw ();
00176 ~condition_variable_any() throw ();
00177
00178 condition_variable_any(const condition_variable_any&) = delete;
00179 condition_variable_any& operator=(const condition_variable_any&) = delete;
00180
00181 void
00182 notify_one()
00183 {
00184 lock_guard<mutex> __lock(_M_mutex);
00185 _M_cond.notify_one();
00186 }
00187
00188 void
00189 notify_all()
00190 {
00191 lock_guard<mutex> __lock(_M_mutex);
00192 _M_cond.notify_all();
00193 }
00194
00195 template<typename _Lock>
00196 void
00197 wait(_Lock& __lock)
00198 {
00199 unique_lock<mutex> __my_lock(_M_mutex);
00200 __lock.unlock();
00201 _M_cond.wait(__my_lock);
00202 __lock.lock();
00203 }
00204
00205
00206 template<typename _Lock, typename _Predicate>
00207 void
00208 wait(_Lock& __lock, _Predicate __p)
00209 {
00210 while (!__p())
00211 wait(__lock);
00212 }
00213
00214 template<typename _Lock, typename _Clock, typename _Duration>
00215 cv_status
00216 wait_until(_Lock& __lock,
00217 const chrono::time_point<_Clock, _Duration>& __atime)
00218 {
00219 unique_lock<mutex> __my_lock(_M_mutex);
00220 __lock.unlock();
00221 cv_status __status = _M_cond.wait_until(__my_lock, __atime);
00222 __lock.lock();
00223 return __status;
00224 }
00225
00226 template<typename _Lock, typename _Clock,
00227 typename _Duration, typename _Predicate>
00228 bool
00229 wait_until(_Lock& __lock,
00230 const chrono::time_point<_Clock, _Duration>& __atime,
00231 _Predicate __p)
00232 {
00233 while (!__p())
00234 if (wait_until(__lock, __atime) == cv_status::timeout)
00235 return __p();
00236 return true;
00237 }
00238
00239 template<typename _Lock, typename _Rep, typename _Period>
00240 cv_status
00241 wait_for(_Lock& __lock, const chrono::duration<_Rep, _Period>& __rtime)
00242 { return wait_until(__lock, __clock_t::now() + __rtime); }
00243
00244 template<typename _Lock, typename _Rep,
00245 typename _Period, typename _Predicate>
00246 bool
00247 wait_for(_Lock& __lock,
00248 const chrono::duration<_Rep, _Period>& __rtime, _Predicate __p)
00249 { return wait_until(__lock, __clock_t::now() + __rtime, std::move(__p)); }
00250
00251 native_handle_type
00252 native_handle()
00253 { return _M_cond.native_handle(); }
00254 };
00255
00256
00257 }
00258
00259 #endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1
00260
00261 #endif // __GXX_EXPERIMENTAL_CXX0X__
00262
00263 #endif // _GLIBCXX_CONDITION_VARIABLE