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
00037 #ifndef NVWA_FAST_MUTEX_H
00038 #define NVWA_FAST_MUTEX_H
00039
00040 #include "_nvwa.h"
00041 #include "c++11.h"
00042
00043 # if !defined(_NOTHREADS)
00044 # if !defined(NVWA_USE_CXX11_MUTEX) && HAVE_CXX11_MUTEX != 0 && \
00045 !defined(_WIN32THREADS) && defined(_WIN32) && defined(_MT) && \
00046 (!defined(_MSC_VER) || defined(_DLL))
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 # define NVWA_USE_CXX11_MUTEX 1
00057 # endif
00058
00059 # if !defined(_WIN32THREADS) && \
00060 (defined(_WIN32) && defined(_MT))
00061
00062
00063 # define _WIN32THREADS
00064 # elif !defined(_PTHREADS) && \
00065 defined(_REENTRANT)
00066
00067 # define _PTHREADS
00068 # endif
00069 # endif
00070
00071 # ifndef NVWA_USE_CXX11_MUTEX
00072 # define NVWA_USE_CXX11_MUTEX 0
00073 # endif
00074
00075 # if !defined(_PTHREADS) && !defined(_WIN32THREADS) && \
00076 !defined(_NOTHREADS) && NVWA_USE_CXX11_MUTEX == 0
00077 # define _NOTHREADS
00078 # endif
00079
00080 # if defined(_NOTHREADS)
00081 # if defined(_PTHREADS) || defined(_WIN32THREADS) || \
00082 NVWA_USE_CXX11_MUTEX != 0
00083 # undef _NOTHREADS
00084 # error "Cannot define multi-threaded mode with -D_NOTHREADS"
00085 # endif
00086 # endif
00087
00088 # if defined(__MINGW32__) && defined(_WIN32THREADS) && !defined(_MT)
00089 # error "Be sure to specify -mthreads with -D_WIN32THREADS"
00090 # endif
00091
00092 # ifndef _FAST_MUTEX_CHECK_INITIALIZATION
00093
00101 # define _FAST_MUTEX_CHECK_INITIALIZATION 1
00102 # endif
00103
00104 # if defined(_PTHREADS) && defined(_WIN32THREADS)
00105
00106
00107 # undef _PTHREADS
00108 # endif
00109
00110 # ifdef _DEBUG
00111 # include <stdio.h>
00112 # include <stdlib.h>
00114 # define _FAST_MUTEX_ASSERT(_Expr, _Msg) \
00115 if (!(_Expr)) { \
00116 fprintf(stderr, "fast_mutex::%s\n", _Msg); \
00117 abort(); \
00118 }
00119 # else
00120
00121 # define _FAST_MUTEX_ASSERT(_Expr, _Msg) \
00122 ((void)0)
00123 # endif
00124
00125 # if NVWA_USE_CXX11_MUTEX != 0
00126 # include <mutex>
00127 NVWA_NAMESPACE_BEGIN
00132 # define __VOLATILE volatile
00133
00137 class fast_mutex
00138 {
00139 std::mutex _M_mtx_impl;
00140 # if _FAST_MUTEX_CHECK_INITIALIZATION
00141 bool _M_initialized;
00142 # endif
00143 # ifdef _DEBUG
00144 bool _M_locked;
00145 # endif
00146 public:
00147 fast_mutex()
00148 # ifdef _DEBUG
00149 : _M_locked(false)
00150 # endif
00151 {
00152 # if _FAST_MUTEX_CHECK_INITIALIZATION
00153 _M_initialized = true;
00154 # endif
00155 }
00156 ~fast_mutex()
00157 {
00158 _FAST_MUTEX_ASSERT(!_M_locked, "~fast_mutex(): still locked");
00159 # if _FAST_MUTEX_CHECK_INITIALIZATION
00160 _M_initialized = false;
00161 # endif
00162 }
00163 void lock()
00164 {
00165 # if _FAST_MUTEX_CHECK_INITIALIZATION
00166 if (!_M_initialized)
00167 return;
00168 # endif
00169 _M_mtx_impl.lock();
00170 # ifdef _DEBUG
00171 _FAST_MUTEX_ASSERT(!_M_locked, "lock(): already locked");
00172 _M_locked = true;
00173 # endif
00174 }
00175 void unlock()
00176 {
00177 # if _FAST_MUTEX_CHECK_INITIALIZATION
00178 if (!_M_initialized)
00179 return;
00180 # endif
00181 # ifdef _DEBUG
00182 _FAST_MUTEX_ASSERT(_M_locked, "unlock(): not locked");
00183 _M_locked = false;
00184 # endif
00185 _M_mtx_impl.unlock();
00186 }
00187 private:
00188 fast_mutex(const fast_mutex&);
00189 fast_mutex& operator=(const fast_mutex&);
00190 };
00191 NVWA_NAMESPACE_END
00192 # endif // NVWA_USE_CXX11_MUTEX != 0
00193
00194 # if defined(_PTHREADS) && NVWA_USE_CXX11_MUTEX == 0
00195 # include <pthread.h>
00196 NVWA_NAMESPACE_BEGIN
00201 # define __VOLATILE volatile
00202
00206 class fast_mutex
00207 {
00208 pthread_mutex_t _M_mtx_impl;
00209 # if _FAST_MUTEX_CHECK_INITIALIZATION
00210 bool _M_initialized;
00211 # endif
00212 # ifdef _DEBUG
00213 bool _M_locked;
00214 # endif
00215 public:
00216 fast_mutex()
00217 # ifdef _DEBUG
00218 : _M_locked(false)
00219 # endif
00220 {
00221 ::pthread_mutex_init(&_M_mtx_impl, NULL);
00222 # if _FAST_MUTEX_CHECK_INITIALIZATION
00223 _M_initialized = true;
00224 # endif
00225 }
00226 ~fast_mutex()
00227 {
00228 _FAST_MUTEX_ASSERT(!_M_locked, "~fast_mutex(): still locked");
00229 # if _FAST_MUTEX_CHECK_INITIALIZATION
00230 _M_initialized = false;
00231 # endif
00232 ::pthread_mutex_destroy(&_M_mtx_impl);
00233 }
00234 void lock()
00235 {
00236 # if _FAST_MUTEX_CHECK_INITIALIZATION
00237 if (!_M_initialized)
00238 return;
00239 # endif
00240 ::pthread_mutex_lock(&_M_mtx_impl);
00241 # ifdef _DEBUG
00242
00243
00244
00245
00246
00247 _FAST_MUTEX_ASSERT(!_M_locked, "lock(): already locked");
00248 _M_locked = true;
00249 # endif
00250 }
00251 void unlock()
00252 {
00253 # if _FAST_MUTEX_CHECK_INITIALIZATION
00254 if (!_M_initialized)
00255 return;
00256 # endif
00257 # ifdef _DEBUG
00258 _FAST_MUTEX_ASSERT(_M_locked, "unlock(): not locked");
00259 _M_locked = false;
00260 # endif
00261 ::pthread_mutex_unlock(&_M_mtx_impl);
00262 }
00263 private:
00264 fast_mutex(const fast_mutex&);
00265 fast_mutex& operator=(const fast_mutex&);
00266 };
00267 NVWA_NAMESPACE_END
00268 # endif // _PTHREADS
00269
00270 # if defined(_WIN32THREADS) && NVWA_USE_CXX11_MUTEX == 0
00271 # ifndef WIN32_LEAN_AND_MEAN
00272 # define WIN32_LEAN_AND_MEAN
00273 # endif
00274 # include <windows.h>
00275 NVWA_NAMESPACE_BEGIN
00280 # define __VOLATILE volatile
00281
00285 class fast_mutex
00286 {
00287 CRITICAL_SECTION _M_mtx_impl;
00288 # if _FAST_MUTEX_CHECK_INITIALIZATION
00289 bool _M_initialized;
00290 # endif
00291 # ifdef _DEBUG
00292 bool _M_locked;
00293 # endif
00294 public:
00295 fast_mutex()
00296 # ifdef _DEBUG
00297 : _M_locked(false)
00298 # endif
00299 {
00300 ::InitializeCriticalSection(&_M_mtx_impl);
00301 # if _FAST_MUTEX_CHECK_INITIALIZATION
00302 _M_initialized = true;
00303 # endif
00304 }
00305 ~fast_mutex()
00306 {
00307 _FAST_MUTEX_ASSERT(!_M_locked, "~fast_mutex(): still locked");
00308 # if _FAST_MUTEX_CHECK_INITIALIZATION
00309 _M_initialized = false;
00310 # endif
00311 ::DeleteCriticalSection(&_M_mtx_impl);
00312 }
00313 void lock()
00314 {
00315 # if _FAST_MUTEX_CHECK_INITIALIZATION
00316 if (!_M_initialized)
00317 return;
00318 # endif
00319 ::EnterCriticalSection(&_M_mtx_impl);
00320 # ifdef _DEBUG
00321 _FAST_MUTEX_ASSERT(!_M_locked, "lock(): already locked");
00322 _M_locked = true;
00323 # endif
00324 }
00325 void unlock()
00326 {
00327 # if _FAST_MUTEX_CHECK_INITIALIZATION
00328 if (!_M_initialized)
00329 return;
00330 # endif
00331 # ifdef _DEBUG
00332 _FAST_MUTEX_ASSERT(_M_locked, "unlock(): not locked");
00333 _M_locked = false;
00334 # endif
00335 ::LeaveCriticalSection(&_M_mtx_impl);
00336 }
00337 private:
00338 fast_mutex(const fast_mutex&);
00339 fast_mutex& operator=(const fast_mutex&);
00340 };
00341 NVWA_NAMESPACE_END
00342 # endif // _WIN32THREADS
00343
00344 # ifdef _NOTHREADS
00345 NVWA_NAMESPACE_BEGIN
00350 # define __VOLATILE
00351
00355 class fast_mutex
00356 {
00357 # ifdef _DEBUG
00358 bool _M_locked;
00359 # endif
00360 public:
00361 fast_mutex()
00362 # ifdef _DEBUG
00363 : _M_locked(false)
00364 # endif
00365 {
00366 }
00367 ~fast_mutex()
00368 {
00369 _FAST_MUTEX_ASSERT(!_M_locked, "~fast_mutex(): still locked");
00370 }
00371 void lock()
00372 {
00373 # ifdef _DEBUG
00374 _FAST_MUTEX_ASSERT(!_M_locked, "lock(): already locked");
00375 _M_locked = true;
00376 # endif
00377 }
00378 void unlock()
00379 {
00380 # ifdef _DEBUG
00381 _FAST_MUTEX_ASSERT(_M_locked, "unlock(): not locked");
00382 _M_locked = false;
00383 # endif
00384 }
00385 private:
00386 fast_mutex(const fast_mutex&);
00387 fast_mutex& operator=(const fast_mutex&);
00388 };
00389 NVWA_NAMESPACE_END
00390 # endif // _NOTHREADS
00391
00392 NVWA_NAMESPACE_BEGIN
00394 class fast_mutex_autolock
00395 {
00396 fast_mutex& _M_mtx;
00397 public:
00398 explicit fast_mutex_autolock(fast_mutex& mtx) : _M_mtx(mtx)
00399 {
00400 _M_mtx.lock();
00401 }
00402 ~fast_mutex_autolock()
00403 {
00404 _M_mtx.unlock();
00405 }
00406 private:
00407 fast_mutex_autolock(const fast_mutex_autolock&);
00408 fast_mutex_autolock& operator=(const fast_mutex_autolock&);
00409 };
00410 NVWA_NAMESPACE_END
00411
00412 #endif // NVWA_FAST_MUTEX_H