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