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