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