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
00030 #ifndef _CONCURRENCE_H
00031 #define _CONCURRENCE_H 1
00032
00033 #pragma GCC system_header
00034
00035 #include <exception>
00036 #include <bits/gthr.h>
00037 #include <bits/functexcept.h>
00038 #include <bits/cpp_type_traits.h>
00039 #include <ext/type_traits.h>
00040
00041 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
00042 {
00043 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00044
00045
00046
00047
00048
00049
00050 enum _Lock_policy { _S_single, _S_mutex, _S_atomic };
00051
00052
00053
00054 static const _Lock_policy __default_lock_policy =
00055 #ifdef __GTHREADS
00056 #if (defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) \
00057 && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4))
00058 _S_atomic;
00059 #else
00060 _S_mutex;
00061 #endif
00062 #else
00063 _S_single;
00064 #endif
00065
00066
00067
00068 class __concurrence_lock_error : public std::exception
00069 {
00070 public:
00071 virtual char const*
00072 what() const throw()
00073 { return "__gnu_cxx::__concurrence_lock_error"; }
00074 };
00075
00076 class __concurrence_unlock_error : public std::exception
00077 {
00078 public:
00079 virtual char const*
00080 what() const throw()
00081 { return "__gnu_cxx::__concurrence_unlock_error"; }
00082 };
00083
00084 class __concurrence_broadcast_error : public std::exception
00085 {
00086 public:
00087 virtual char const*
00088 what() const throw()
00089 { return "__gnu_cxx::__concurrence_broadcast_error"; }
00090 };
00091
00092 class __concurrence_wait_error : public std::exception
00093 {
00094 public:
00095 virtual char const*
00096 what() const throw()
00097 { return "__gnu_cxx::__concurrence_wait_error"; }
00098 };
00099
00100
00101 inline void
00102 __throw_concurrence_lock_error()
00103 {
00104 #if __EXCEPTIONS
00105 throw __concurrence_lock_error();
00106 #else
00107 __builtin_abort();
00108 #endif
00109 }
00110
00111 inline void
00112 __throw_concurrence_unlock_error()
00113 {
00114 #if __EXCEPTIONS
00115 throw __concurrence_unlock_error();
00116 #else
00117 __builtin_abort();
00118 #endif
00119 }
00120
00121 #ifdef __GTHREAD_HAS_COND
00122 inline void
00123 __throw_concurrence_broadcast_error()
00124 {
00125 #if __EXCEPTIONS
00126 throw __concurrence_broadcast_error();
00127 #else
00128 __builtin_abort();
00129 #endif
00130 }
00131
00132 inline void
00133 __throw_concurrence_wait_error()
00134 {
00135 #if __EXCEPTIONS
00136 throw __concurrence_wait_error();
00137 #else
00138 __builtin_abort();
00139 #endif
00140 }
00141 #endif
00142
00143 class __mutex
00144 {
00145 private:
00146 __gthread_mutex_t _M_mutex;
00147
00148 __mutex(const __mutex&);
00149 __mutex& operator=(const __mutex&);
00150
00151 public:
00152 __mutex()
00153 {
00154 #if __GTHREADS
00155 if (__gthread_active_p())
00156 {
00157 #if defined __GTHREAD_MUTEX_INIT
00158 __gthread_mutex_t __tmp = __GTHREAD_MUTEX_INIT;
00159 _M_mutex = __tmp;
00160 #else
00161 __GTHREAD_MUTEX_INIT_FUNCTION(&_M_mutex);
00162 #endif
00163 }
00164 #endif
00165 }
00166
00167 #if __GTHREADS && ! defined __GTHREAD_MUTEX_INIT
00168 ~__mutex()
00169 {
00170 if (__gthread_active_p())
00171 __gthread_mutex_destroy(&_M_mutex);
00172 }
00173 #endif
00174
00175 void lock()
00176 {
00177 #if __GTHREADS
00178 if (__gthread_active_p())
00179 {
00180 if (__gthread_mutex_lock(&_M_mutex) != 0)
00181 __throw_concurrence_lock_error();
00182 }
00183 #endif
00184 }
00185
00186 void unlock()
00187 {
00188 #if __GTHREADS
00189 if (__gthread_active_p())
00190 {
00191 if (__gthread_mutex_unlock(&_M_mutex) != 0)
00192 __throw_concurrence_unlock_error();
00193 }
00194 #endif
00195 }
00196
00197 __gthread_mutex_t* gthread_mutex(void)
00198 { return &_M_mutex; }
00199 };
00200
00201 class __recursive_mutex
00202 {
00203 private:
00204 __gthread_recursive_mutex_t _M_mutex;
00205
00206 __recursive_mutex(const __recursive_mutex&);
00207 __recursive_mutex& operator=(const __recursive_mutex&);
00208
00209 public:
00210 __recursive_mutex()
00211 {
00212 #if __GTHREADS
00213 if (__gthread_active_p())
00214 {
00215 #if defined __GTHREAD_RECURSIVE_MUTEX_INIT
00216 __gthread_recursive_mutex_t __tmp = __GTHREAD_RECURSIVE_MUTEX_INIT;
00217 _M_mutex = __tmp;
00218 #else
00219 __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION(&_M_mutex);
00220 #endif
00221 }
00222 #endif
00223 }
00224
00225 #if __GTHREADS && ! defined __GTHREAD_RECURSIVE_MUTEX_INIT
00226 ~__recursive_mutex()
00227 {
00228 if (__gthread_active_p())
00229 _S_destroy(&_M_mutex);
00230 }
00231 #endif
00232
00233 void lock()
00234 {
00235 #if __GTHREADS
00236 if (__gthread_active_p())
00237 {
00238 if (__gthread_recursive_mutex_lock(&_M_mutex) != 0)
00239 __throw_concurrence_lock_error();
00240 }
00241 #endif
00242 }
00243
00244 void unlock()
00245 {
00246 #if __GTHREADS
00247 if (__gthread_active_p())
00248 {
00249 if (__gthread_recursive_mutex_unlock(&_M_mutex) != 0)
00250 __throw_concurrence_unlock_error();
00251 }
00252 #endif
00253 }
00254
00255 __gthread_recursive_mutex_t* gthread_recursive_mutex(void)
00256 { return &_M_mutex; }
00257
00258 #if __GTHREADS && ! defined __GTHREAD_RECURSIVE_MUTEX_INIT
00259
00260
00261 private:
00262 template<typename _Mx, typename _Rm>
00263 static void
00264 _S_destroy_win32(_Mx* __mx, _Rm const* __rmx)
00265 {
00266 __mx->counter = __rmx->counter;
00267 __mx->sema = __rmx->sema;
00268 __gthread_mutex_destroy(__mx);
00269 }
00270
00271
00272 template<typename _Rm>
00273 static typename __enable_if<sizeof(&_Rm::sema), void>::__type
00274 _S_destroy(_Rm* __mx)
00275 {
00276 __gthread_mutex_t __tmp;
00277 _S_destroy_win32(&__tmp, __mx);
00278 }
00279
00280
00281 template<typename _Rm>
00282 static typename __enable_if<sizeof(&_Rm::actual), void>::__type
00283 _S_destroy(_Rm* __mx)
00284 { __gthread_mutex_destroy(&__mx->actual); }
00285
00286
00287 template<typename _Rm>
00288 static typename
00289 __enable_if<std::__are_same<_Rm, __gthread_mutex_t>::__value,
00290 void>::__type
00291 _S_destroy(_Rm* __mx)
00292 { __gthread_mutex_destroy(__mx); }
00293 #endif
00294 };
00295
00296
00297
00298
00299 class __scoped_lock
00300 {
00301 public:
00302 typedef __mutex __mutex_type;
00303
00304 private:
00305 __mutex_type& _M_device;
00306
00307 __scoped_lock(const __scoped_lock&);
00308 __scoped_lock& operator=(const __scoped_lock&);
00309
00310 public:
00311 explicit __scoped_lock(__mutex_type& __name) : _M_device(__name)
00312 { _M_device.lock(); }
00313
00314 ~__scoped_lock() throw()
00315 { _M_device.unlock(); }
00316 };
00317
00318 #ifdef __GTHREAD_HAS_COND
00319 class __cond
00320 {
00321 private:
00322 __gthread_cond_t _M_cond;
00323
00324 __cond(const __cond&);
00325 __cond& operator=(const __cond&);
00326
00327 public:
00328 __cond()
00329 {
00330 #if __GTHREADS
00331 if (__gthread_active_p())
00332 {
00333 #if defined __GTHREAD_COND_INIT
00334 __gthread_cond_t __tmp = __GTHREAD_COND_INIT;
00335 _M_cond = __tmp;
00336 #else
00337 __GTHREAD_COND_INIT_FUNCTION(&_M_cond);
00338 #endif
00339 }
00340 #endif
00341 }
00342
00343 #if __GTHREADS && ! defined __GTHREAD_COND_INIT
00344 ~__cond()
00345 {
00346 if (__gthread_active_p())
00347 __gthread_cond_destroy(&_M_cond);
00348 }
00349 #endif
00350
00351 void broadcast()
00352 {
00353 #if __GTHREADS
00354 if (__gthread_active_p())
00355 {
00356 if (__gthread_cond_broadcast(&_M_cond) != 0)
00357 __throw_concurrence_broadcast_error();
00358 }
00359 #endif
00360 }
00361
00362 void wait(__mutex *mutex)
00363 {
00364 #if __GTHREADS
00365 {
00366 if (__gthread_cond_wait(&_M_cond, mutex->gthread_mutex()) != 0)
00367 __throw_concurrence_wait_error();
00368 }
00369 #endif
00370 }
00371
00372 void wait_recursive(__recursive_mutex *mutex)
00373 {
00374 #if __GTHREADS
00375 {
00376 if (__gthread_cond_wait_recursive(&_M_cond,
00377 mutex->gthread_recursive_mutex())
00378 != 0)
00379 __throw_concurrence_wait_error();
00380 }
00381 #endif
00382 }
00383 };
00384 #endif
00385
00386 _GLIBCXX_END_NAMESPACE_VERSION
00387 }
00388
00389 #endif