fast_mutex.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
00039 #ifndef _FAST_MUTEX_H
00040 #define _FAST_MUTEX_H
00041
00042 # if !defined(_NOTHREADS)
00043 # if !defined(_WIN32THREADS) && \
00044 (defined(_WIN32) && defined(_MT))
00045
00046
00047 # define _WIN32THREADS
00048 # elif !defined(_PTHREADS) && \
00049 defined(_REENTRANT)
00050
00051
00052
00053 # define _PTHREADS
00054 # endif
00055 # endif
00056
00057 # if !defined(_PTHREADS) && !defined(_WIN32THREADS) && !defined(_NOTHREADS)
00058 # define _NOTHREADS
00059 # endif
00060
00061 # if defined(_NOTHREADS)
00062 # if defined(_PTHREADS) || defined(_WIN32THREADS)
00063 # undef _NOTHREADS
00064 # error "Cannot define multi-threaded mode with -D_NOTHREADS"
00065 # if defined(__MINGW32__) && defined(_WIN32THREADS) && !defined(_MT)
00066 # error "Be sure to specify -mthreads with -D_WIN32THREADS"
00067 # endif
00068 # endif
00069 # endif
00070
00071 # ifndef _FAST_MUTEX_CHECK_INITIALIZATION
00072
00080 # define _FAST_MUTEX_CHECK_INITIALIZATION 1
00081 # endif
00082
00083 # if defined(_PTHREADS) && defined(_WIN32THREADS)
00084
00085
00086 # undef _PTHREADS
00087 # endif
00088
00089 # ifdef _DEBUG
00090 # include <stdio.h>
00091 # include <stdlib.h>
00093 # define _FAST_MUTEX_ASSERT(_Expr, _Msg) \
00094 if (!(_Expr)) { \
00095 fprintf(stderr, "fast_mutex::%s\n", _Msg); \
00096 abort(); \
00097 }
00098 # else
00099
00100 # define _FAST_MUTEX_ASSERT(_Expr, _Msg) \
00101 ((void)0)
00102 # endif
00103
00104 # ifdef _PTHREADS
00105 # include <pthread.h>
00110 # define __VOLATILE volatile
00111
00115 class fast_mutex
00116 {
00117 pthread_mutex_t _M_mtx_impl;
00118 # if _FAST_MUTEX_CHECK_INITIALIZATION
00119 bool _M_initialized;
00120 # endif
00121 # ifdef _DEBUG
00122 bool _M_locked;
00123 # endif
00124 public:
00125 fast_mutex()
00126 # ifdef _DEBUG
00127 : _M_locked(false)
00128 # endif
00129 {
00130 ::pthread_mutex_init(&_M_mtx_impl, NULL);
00131 # if _FAST_MUTEX_CHECK_INITIALIZATION
00132 _M_initialized = true;
00133 # endif
00134 }
00135 ~fast_mutex()
00136 {
00137 _FAST_MUTEX_ASSERT(!_M_locked, "~fast_mutex(): still locked");
00138 # if _FAST_MUTEX_CHECK_INITIALIZATION
00139 _M_initialized = false;
00140 # endif
00141 ::pthread_mutex_destroy(&_M_mtx_impl);
00142 }
00143 void lock()
00144 {
00145 # if _FAST_MUTEX_CHECK_INITIALIZATION
00146 if (!_M_initialized)
00147 return;
00148 # endif
00149 ::pthread_mutex_lock(&_M_mtx_impl);
00150 # ifdef _DEBUG
00151
00152
00153
00154
00155
00156 _FAST_MUTEX_ASSERT(!_M_locked, "lock(): already locked");
00157 _M_locked = true;
00158 # endif
00159 }
00160 void unlock()
00161 {
00162 # if _FAST_MUTEX_CHECK_INITIALIZATION
00163 if (!_M_initialized)
00164 return;
00165 # endif
00166 # ifdef _DEBUG
00167 _FAST_MUTEX_ASSERT(_M_locked, "unlock(): not locked");
00168 _M_locked = false;
00169 # endif
00170 ::pthread_mutex_unlock(&_M_mtx_impl);
00171 }
00172 private:
00173 fast_mutex(const fast_mutex&);
00174 fast_mutex& operator=(const fast_mutex&);
00175 };
00176 # endif // _PTHREADS
00177
00178 # ifdef _WIN32THREADS
00179 # include <windows.h>
00184 # define __VOLATILE volatile
00185
00189 class fast_mutex
00190 {
00191 CRITICAL_SECTION _M_mtx_impl;
00192 # if _FAST_MUTEX_CHECK_INITIALIZATION
00193 bool _M_initialized;
00194 # endif
00195 # ifdef _DEBUG
00196 bool _M_locked;
00197 # endif
00198 public:
00199 fast_mutex()
00200 # ifdef _DEBUG
00201 : _M_locked(false)
00202 # endif
00203 {
00204 ::InitializeCriticalSection(&_M_mtx_impl);
00205 # if _FAST_MUTEX_CHECK_INITIALIZATION
00206 _M_initialized = true;
00207 # endif
00208 }
00209 ~fast_mutex()
00210 {
00211 _FAST_MUTEX_ASSERT(!_M_locked, "~fast_mutex(): still locked");
00212 # if _FAST_MUTEX_CHECK_INITIALIZATION
00213 _M_initialized = false;
00214 # endif
00215 ::DeleteCriticalSection(&_M_mtx_impl);
00216 }
00217 void lock()
00218 {
00219 # if _FAST_MUTEX_CHECK_INITIALIZATION
00220 if (!_M_initialized)
00221 return;
00222 # endif
00223 ::EnterCriticalSection(&_M_mtx_impl);
00224 # ifdef _DEBUG
00225 _FAST_MUTEX_ASSERT(!_M_locked, "lock(): already locked");
00226 _M_locked = true;
00227 # endif
00228 }
00229 void unlock()
00230 {
00231 # if _FAST_MUTEX_CHECK_INITIALIZATION
00232 if (!_M_initialized)
00233 return;
00234 # endif
00235 # ifdef _DEBUG
00236 _FAST_MUTEX_ASSERT(_M_locked, "unlock(): not locked");
00237 _M_locked = false;
00238 # endif
00239 ::LeaveCriticalSection(&_M_mtx_impl);
00240 }
00241 private:
00242 fast_mutex(const fast_mutex&);
00243 fast_mutex& operator=(const fast_mutex&);
00244 };
00245 # endif // _WIN32THREADS
00246
00247 # ifdef _NOTHREADS
00248
00252 # define __VOLATILE
00253
00257 class fast_mutex
00258 {
00259 # ifdef _DEBUG
00260 bool _M_locked;
00261 # endif
00262 public:
00263 fast_mutex()
00264 # ifdef _DEBUG
00265 : _M_locked(false)
00266 # endif
00267 {
00268 }
00269 ~fast_mutex()
00270 {
00271 _FAST_MUTEX_ASSERT(!_M_locked, "~fast_mutex(): still locked");
00272 }
00273 void lock()
00274 {
00275 # ifdef _DEBUG
00276 _FAST_MUTEX_ASSERT(!_M_locked, "lock(): already locked");
00277 _M_locked = true;
00278 # endif
00279 }
00280 void unlock()
00281 {
00282 # ifdef _DEBUG
00283 _FAST_MUTEX_ASSERT(_M_locked, "unlock(): not locked");
00284 _M_locked = false;
00285 # endif
00286 }
00287 private:
00288 fast_mutex(const fast_mutex&);
00289 fast_mutex& operator=(const fast_mutex&);
00290 };
00291 # endif // _NOTHREADS
00292
00294 class fast_mutex_autolock
00295 {
00296 fast_mutex& _M_mtx;
00297 public:
00298 explicit fast_mutex_autolock(fast_mutex& __mtx) : _M_mtx(__mtx)
00299 {
00300 _M_mtx.lock();
00301 }
00302 ~fast_mutex_autolock()
00303 {
00304 _M_mtx.unlock();
00305 }
00306 private:
00307 fast_mutex_autolock(const fast_mutex_autolock&);
00308 fast_mutex_autolock& operator=(const fast_mutex_autolock&);
00309 };
00310
00311 #endif // _FAST_MUTEX_H