SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
fast_mutex.h
Go to the documentation of this file.
1 // -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
2 // vim:tabstop=4:shiftwidth=4:expandtab:
3 
4 /*
5  * Copyright (C) 2004-2010 Wu Yongwei <adah at users dot sourceforge dot net>
6  *
7  * This software is provided 'as-is', without any express or implied
8  * warranty. In no event will the authors be held liable for any
9  * damages arising from the use of this software.
10  *
11  * Permission is granted to anyone to use this software for any purpose,
12  * including commercial applications, and to alter it and redistribute
13  * it freely, subject to the following restrictions:
14  *
15  * 1. The origin of this software must not be misrepresented; you must
16  * not claim that you wrote the original software. If you use this
17  * software in a product, an acknowledgement in the product
18  * documentation would be appreciated but is not required.
19  * 2. Altered source versions must be plainly marked as such, and must
20  * not be misrepresented as being the original software.
21  * 3. This notice may not be removed or altered from any source
22  * distribution.
23  *
24  * This file is part of Stones of Nvwa:
25  * http://sourceforge.net/projects/nvwa
26  *
27  */
28 
39 #ifndef _FAST_MUTEX_H
40 #define _FAST_MUTEX_H
41 
42 # if !defined(_NOTHREADS)
43 # if !defined(_WIN32THREADS) && \
44  (defined(_WIN32) && defined(_MT))
45 // Automatically use _WIN32THREADS when specifying -MT/-MD in MSVC,
46 // or -mthreads in MinGW GCC.
47 # define _WIN32THREADS
48 # elif !defined(_PTHREADS) && \
49  defined(_REENTRANT)
50 // Automatically use _PTHREADS when specifying -pthread in GCC.
51 // N.B. I do not detect on _PTHREAD_H since libstdc++-v3 under
52 // Linux will silently include <pthread.h> anyway.
53 # define _PTHREADS
54 # endif
55 # endif
56 
57 # if !defined(_PTHREADS) && !defined(_WIN32THREADS) && !defined(_NOTHREADS)
58 # define _NOTHREADS
59 # endif
60 
61 # if defined(_NOTHREADS)
62 # if defined(_PTHREADS) || defined(_WIN32THREADS)
63 # undef _NOTHREADS
64 # error "Cannot define multi-threaded mode with -D_NOTHREADS"
65 # if defined(__MINGW32__) && defined(_WIN32THREADS) && !defined(_MT)
66 # error "Be sure to specify -mthreads with -D_WIN32THREADS"
67 # endif
68 # endif
69 # endif
70 
71 # ifndef _FAST_MUTEX_CHECK_INITIALIZATION
72 
80 # define _FAST_MUTEX_CHECK_INITIALIZATION 1
81 # endif
82 
83 # if defined(_PTHREADS) && defined(_WIN32THREADS)
84 // Some C++ libraries have _PTHREADS defined even on Win32 platforms.
85 // Thus this hack.
86 # undef _PTHREADS
87 # endif
88 
89 # ifdef _DEBUG
90 # include <stdio.h>
91 # include <stdlib.h>
93 # define _FAST_MUTEX_ASSERT(_Expr, _Msg) \
94  if (!(_Expr)) { \
95  fprintf(stderr, "fast_mutex::%s\n", _Msg); \
96  abort(); \
97  }
98 # else
99 
100 # define _FAST_MUTEX_ASSERT(_Expr, _Msg) \
101  ((void)0)
102 # endif
103 
104 # ifdef _PTHREADS
105 # include <pthread.h>
110 # define __VOLATILE volatile
111 
115  class fast_mutex
116  {
117  pthread_mutex_t _M_mtx_impl;
118 # if _FAST_MUTEX_CHECK_INITIALIZATION
119  bool _M_initialized;
120 # endif
121 # ifdef _DEBUG
122  bool _M_locked;
123 # endif
124  public:
125  fast_mutex()
126 # ifdef _DEBUG
127  : _M_locked(false)
128 # endif
129  {
130  ::pthread_mutex_init(&_M_mtx_impl, NULL);
131 # if _FAST_MUTEX_CHECK_INITIALIZATION
132  _M_initialized = true;
133 # endif
134  }
135  ~fast_mutex()
136  {
137  _FAST_MUTEX_ASSERT(!_M_locked, "~fast_mutex(): still locked");
138 # if _FAST_MUTEX_CHECK_INITIALIZATION
139  _M_initialized = false;
140 # endif
141  ::pthread_mutex_destroy(&_M_mtx_impl);
142  }
143  void lock()
144  {
145 # if _FAST_MUTEX_CHECK_INITIALIZATION
146  if (!_M_initialized)
147  return;
148 # endif
149  ::pthread_mutex_lock(&_M_mtx_impl);
150 # ifdef _DEBUG
151  // The following assertion should _always_ be true for a
152  // real `fast' pthread_mutex. However, this assertion can
153  // help sometimes, when people forget to use `-lpthread' and
154  // glibc provides an empty implementation. Having this
155  // assertion is also more consistent.
156  _FAST_MUTEX_ASSERT(!_M_locked, "lock(): already locked");
157  _M_locked = true;
158 # endif
159  }
160  void unlock()
161  {
162 # if _FAST_MUTEX_CHECK_INITIALIZATION
163  if (!_M_initialized)
164  return;
165 # endif
166 # ifdef _DEBUG
167  _FAST_MUTEX_ASSERT(_M_locked, "unlock(): not locked");
168  _M_locked = false;
169 # endif
170  ::pthread_mutex_unlock(&_M_mtx_impl);
171  }
172  private:
173  fast_mutex(const fast_mutex&);
175  };
176 # endif // _PTHREADS
177 
178 # ifdef _WIN32THREADS
179 # ifndef WIN32_LEAN_AND_MEAN
180 # define WIN32_LEAN_AND_MEAN
181 # endif /* WIN32_LEAN_AND_MEAN */
182 # include <windows.h>
187 # define __VOLATILE volatile
188 
192  class fast_mutex
193  {
194  CRITICAL_SECTION _M_mtx_impl;
195 # if _FAST_MUTEX_CHECK_INITIALIZATION
196  bool _M_initialized;
197 # endif
198 # ifdef _DEBUG
199  bool _M_locked;
200 # endif
201  public:
202  fast_mutex()
203 # ifdef _DEBUG
204  : _M_locked(false)
205 # endif
206  {
207  ::InitializeCriticalSection(&_M_mtx_impl);
208 # if _FAST_MUTEX_CHECK_INITIALIZATION
209  _M_initialized = true;
210 # endif
211  }
212  ~fast_mutex()
213  {
214  _FAST_MUTEX_ASSERT(!_M_locked, "~fast_mutex(): still locked");
215 # if _FAST_MUTEX_CHECK_INITIALIZATION
216  _M_initialized = false;
217 # endif
218  ::DeleteCriticalSection(&_M_mtx_impl);
219  }
220  void lock()
221  {
222 # if _FAST_MUTEX_CHECK_INITIALIZATION
223  if (!_M_initialized)
224  return;
225 # endif
226  ::EnterCriticalSection(&_M_mtx_impl);
227 # ifdef _DEBUG
228  _FAST_MUTEX_ASSERT(!_M_locked, "lock(): already locked");
229  _M_locked = true;
230 # endif
231  }
232  void unlock()
233  {
234 # if _FAST_MUTEX_CHECK_INITIALIZATION
235  if (!_M_initialized)
236  return;
237 # endif
238 # ifdef _DEBUG
239  _FAST_MUTEX_ASSERT(_M_locked, "unlock(): not locked");
240  _M_locked = false;
241 # endif
242  ::LeaveCriticalSection(&_M_mtx_impl);
243  }
244  private:
245  fast_mutex(const fast_mutex&);
247  };
248 # endif // _WIN32THREADS
249 
250 # ifdef _NOTHREADS
251 
255 # define __VOLATILE
256 
261  {
262 # ifdef _DEBUG
263  bool _M_locked;
264 # endif
265  public:
267 # ifdef _DEBUG
268  : _M_locked(false)
269 # endif
270  {
271  }
273  {
274  _FAST_MUTEX_ASSERT(!_M_locked, "~fast_mutex(): still locked");
275  }
276  void lock()
277  {
278 # ifdef _DEBUG
279  _FAST_MUTEX_ASSERT(!_M_locked, "lock(): already locked");
280  _M_locked = true;
281 # endif
282  }
283  void unlock()
284  {
285 # ifdef _DEBUG
286  _FAST_MUTEX_ASSERT(_M_locked, "unlock(): not locked");
287  _M_locked = false;
288 # endif
289  }
290  private:
291  fast_mutex(const fast_mutex&);
293  };
294 # endif // _NOTHREADS
295 
298 {
300 public:
301  explicit fast_mutex_autolock(fast_mutex& mtx) : _M_mtx(mtx)
302  {
303  _M_mtx.lock();
304  }
306  {
307  _M_mtx.unlock();
308  }
309 private:
312 };
313 
314 #endif // _FAST_MUTEX_H
fast_mutex_autolock & operator=(const fast_mutex_autolock &)
void lock()
Definition: fast_mutex.h:276
fast_mutex_autolock(fast_mutex &mtx)
Definition: fast_mutex.h:301
fast_mutex & operator=(const fast_mutex &)
#define _FAST_MUTEX_ASSERT(_Expr, _Msg)
Definition: fast_mutex.h:100
fast_mutex & _M_mtx
Definition: fast_mutex.h:299
void unlock()
Definition: fast_mutex.h:283