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
00032
00033
00034
00035
00036 #ifndef _CONCURRENCE_H
00037 #define _CONCURRENCE_H 1
00038
00039 #include <exception>
00040 #include <bits/gthr.h>
00041 #include <bits/functexcept.h>
00042
00043 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
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 void lock()
00168 {
00169 #if __GTHREADS
00170 if (__gthread_active_p())
00171 {
00172 if (__gthread_mutex_lock(&_M_mutex) != 0)
00173 __throw_concurrence_lock_error();
00174 }
00175 #endif
00176 }
00177
00178 void unlock()
00179 {
00180 #if __GTHREADS
00181 if (__gthread_active_p())
00182 {
00183 if (__gthread_mutex_unlock(&_M_mutex) != 0)
00184 __throw_concurrence_unlock_error();
00185 }
00186 #endif
00187 }
00188
00189 __gthread_mutex_t* gthread_mutex(void)
00190 { return &_M_mutex; }
00191 };
00192
00193 class __recursive_mutex
00194 {
00195 private:
00196 __gthread_recursive_mutex_t _M_mutex;
00197
00198 __recursive_mutex(const __recursive_mutex&);
00199 __recursive_mutex& operator=(const __recursive_mutex&);
00200
00201 public:
00202 __recursive_mutex()
00203 {
00204 #if __GTHREADS
00205 if (__gthread_active_p())
00206 {
00207 #if defined __GTHREAD_RECURSIVE_MUTEX_INIT
00208 __gthread_recursive_mutex_t __tmp = __GTHREAD_RECURSIVE_MUTEX_INIT;
00209 _M_mutex = __tmp;
00210 #else
00211 __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION(&_M_mutex);
00212 #endif
00213 }
00214 #endif
00215 }
00216
00217 void lock()
00218 {
00219 #if __GTHREADS
00220 if (__gthread_active_p())
00221 {
00222 if (__gthread_recursive_mutex_lock(&_M_mutex) != 0)
00223 __throw_concurrence_lock_error();
00224 }
00225 #endif
00226 }
00227
00228 void unlock()
00229 {
00230 #if __GTHREADS
00231 if (__gthread_active_p())
00232 {
00233 if (__gthread_recursive_mutex_unlock(&_M_mutex) != 0)
00234 __throw_concurrence_unlock_error();
00235 }
00236 #endif
00237 }
00238
00239 __gthread_recursive_mutex_t* gthread_recursive_mutex(void)
00240 { return &_M_mutex; }
00241 };
00242
00243
00244
00245
00246 class __scoped_lock
00247 {
00248 public:
00249 typedef __mutex __mutex_type;
00250
00251 private:
00252 __mutex_type& _M_device;
00253
00254 __scoped_lock(const __scoped_lock&);
00255 __scoped_lock& operator=(const __scoped_lock&);
00256
00257 public:
00258 explicit __scoped_lock(__mutex_type& __name) : _M_device(__name)
00259 { _M_device.lock(); }
00260
00261 ~__scoped_lock() throw()
00262 { _M_device.unlock(); }
00263 };
00264
00265 #ifdef __GTHREAD_HAS_COND
00266 class __cond
00267 {
00268 private:
00269 __gthread_cond_t _M_cond;
00270
00271 __cond(const __cond&);
00272 __cond& operator=(const __cond&);
00273
00274 public:
00275 __cond()
00276 {
00277 #if __GTHREADS
00278 if (__gthread_active_p())
00279 {
00280 #if defined __GTHREAD_COND_INIT
00281 __gthread_cond_t __tmp = __GTHREAD_COND_INIT;
00282 _M_cond = __tmp;
00283 #else
00284 __GTHREAD_COND_INIT_FUNCTION(&_M_cond);
00285 #endif
00286 }
00287 #endif
00288 }
00289
00290 void broadcast()
00291 {
00292 #if __GTHREADS
00293 if (__gthread_active_p())
00294 {
00295 if (__gthread_cond_broadcast(&_M_cond) != 0)
00296 __throw_concurrence_broadcast_error();
00297 }
00298 #endif
00299 }
00300
00301 void wait(__mutex *mutex)
00302 {
00303 #if __GTHREADS
00304 {
00305 if (__gthread_cond_wait(&_M_cond, mutex->gthread_mutex()) != 0)
00306 __throw_concurrence_wait_error();
00307 }
00308 #endif
00309 }
00310
00311 void wait_recursive(__recursive_mutex *mutex)
00312 {
00313 #if __GTHREADS
00314 {
00315 if (__gthread_cond_wait_recursive(&_M_cond,
00316 mutex->gthread_recursive_mutex())
00317 != 0)
00318 __throw_concurrence_wait_error();
00319 }
00320 #endif
00321 }
00322 };
00323 #endif
00324
00325 _GLIBCXX_END_NAMESPACE
00326
00327 #endif