BRE12
mutex.h
1 /*
2  Copyright 2005-2016 Intel Corporation. All Rights Reserved.
3 
4  This file is part of Threading Building Blocks. Threading Building Blocks is free software;
5  you can redistribute it and/or modify it under the terms of the GNU General Public License
6  version 2 as published by the Free Software Foundation. Threading Building Blocks is
7  distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
8  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9  See the GNU General Public License for more details. You should have received a copy of
10  the GNU General Public License along with Threading Building Blocks; if not, write to the
11  Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
12 
13  As a special exception, you may use this file as part of a free software library without
14  restriction. Specifically, if other files instantiate templates or use macros or inline
15  functions from this file, or you compile this file and link it with other files to produce
16  an executable, this file does not by itself cause the resulting executable to be covered
17  by the GNU General Public License. This exception does not however invalidate any other
18  reasons why the executable file might be covered by the GNU General Public License.
19 */
20 
21 #ifndef __TBB_mutex_H
22 #define __TBB_mutex_H
23 
24 #if _WIN32||_WIN64
25 #include "machine/windows_api.h"
26 #else
27 #include <pthread.h>
28 #endif /* _WIN32||_WIN64 */
29 
30 #include <new>
31 #include "aligned_space.h"
32 #include "tbb_stddef.h"
33 #include "tbb_profiling.h"
34 
35 namespace tbb {
36 
38 
40 class mutex : internal::mutex_copy_deprecated_and_disabled {
41 public:
43  mutex() {
44 #if TBB_USE_ASSERT || TBB_USE_THREADING_TOOLS
45  internal_construct();
46 #else
47  #if _WIN32||_WIN64
48  InitializeCriticalSectionEx(&impl, 4000, 0);
49  #else
50  int error_code = pthread_mutex_init(&impl,NULL);
51  if( error_code )
52  tbb::internal::handle_perror(error_code,"mutex: pthread_mutex_init failed");
53  #endif /* _WIN32||_WIN64*/
54 #endif /* TBB_USE_ASSERT */
55  };
56 
57  ~mutex() {
58 #if TBB_USE_ASSERT
59  internal_destroy();
60 #else
61  #if _WIN32||_WIN64
62  DeleteCriticalSection(&impl);
63  #else
64  pthread_mutex_destroy(&impl);
65 
66  #endif /* _WIN32||_WIN64 */
67 #endif /* TBB_USE_ASSERT */
68  };
69 
70  class scoped_lock;
71  friend class scoped_lock;
72 
74 
76  class scoped_lock : internal::no_copy {
77  public:
79  scoped_lock() : my_mutex(NULL) {};
80 
83  acquire( mutex );
84  }
85 
88  if( my_mutex )
89  release();
90  }
91 
93  void acquire( mutex& mutex ) {
94 #if TBB_USE_ASSERT
95  internal_acquire(mutex);
96 #else
97  mutex.lock();
98  my_mutex = &mutex;
99 #endif /* TBB_USE_ASSERT */
100  }
101 
104 #if TBB_USE_ASSERT
105  return internal_try_acquire (mutex);
106 #else
107  bool result = mutex.try_lock();
108  if( result )
109  my_mutex = &mutex;
110  return result;
111 #endif /* TBB_USE_ASSERT */
112  }
113 
115  void release() {
116 #if TBB_USE_ASSERT
117  internal_release ();
118 #else
119  my_mutex->unlock();
120  my_mutex = NULL;
121 #endif /* TBB_USE_ASSERT */
122  }
123 
124  private:
126  mutex* my_mutex;
127 
129  void __TBB_EXPORTED_METHOD internal_acquire( mutex& m );
130 
132  bool __TBB_EXPORTED_METHOD internal_try_acquire( mutex& m );
133 
135  void __TBB_EXPORTED_METHOD internal_release();
136 
137  friend class mutex;
138  };
139 
140  // Mutex traits
141  static const bool is_rw_mutex = false;
142  static const bool is_recursive_mutex = false;
143  static const bool is_fair_mutex = false;
144 
145  // ISO C++0x compatibility methods
146 
148  void lock() {
149 #if TBB_USE_ASSERT
151  new(tmp.begin()) scoped_lock(*this);
152 #else
153  #if _WIN32||_WIN64
154  EnterCriticalSection(&impl);
155  #else
156  int error_code = pthread_mutex_lock(&impl);
157  if( error_code )
158  tbb::internal::handle_perror(error_code,"mutex: pthread_mutex_lock failed");
159  #endif /* _WIN32||_WIN64 */
160 #endif /* TBB_USE_ASSERT */
161  }
162 
164 
165  bool try_lock() {
166 #if TBB_USE_ASSERT
168  scoped_lock& s = *tmp.begin();
169  s.my_mutex = NULL;
170  return s.internal_try_acquire(*this);
171 #else
172  #if _WIN32||_WIN64
173  return TryEnterCriticalSection(&impl)!=0;
174  #else
175  return pthread_mutex_trylock(&impl)==0;
176  #endif /* _WIN32||_WIN64 */
177 #endif /* TBB_USE_ASSERT */
178  }
179 
181  void unlock() {
182 #if TBB_USE_ASSERT
184  scoped_lock& s = *tmp.begin();
185  s.my_mutex = this;
186  s.internal_release();
187 #else
188  #if _WIN32||_WIN64
189  LeaveCriticalSection(&impl);
190  #else
191  pthread_mutex_unlock(&impl);
192  #endif /* _WIN32||_WIN64 */
193 #endif /* TBB_USE_ASSERT */
194  }
195 
197  #if _WIN32||_WIN64
198  typedef LPCRITICAL_SECTION native_handle_type;
199  #else
200  typedef pthread_mutex_t* native_handle_type;
201  #endif
202  native_handle_type native_handle() { return (native_handle_type) &impl; }
203 
204  enum state_t {
205  INITIALIZED=0x1234,
206  DESTROYED=0x789A,
207  HELD=0x56CD
208  };
209 private:
210 #if _WIN32||_WIN64
211  CRITICAL_SECTION impl;
212  enum state_t state;
213 #else
214  pthread_mutex_t impl;
215 #endif /* _WIN32||_WIN64 */
216 
218  void __TBB_EXPORTED_METHOD internal_construct();
219 
221  void __TBB_EXPORTED_METHOD internal_destroy();
222 
223 #if _WIN32||_WIN64
224 public:
226  void set_state( state_t to ) { state = to; }
227 #endif
228 };
229 
230 __TBB_DEFINE_PROFILING_SET_NAME(mutex)
231 
232 } // namespace tbb
233 
234 #endif /* __TBB_mutex_H */
~scoped_lock()
Release lock (if lock is held).
Definition: mutex.h:87
scoped_lock()
Construct lock that has not acquired a mutex.
Definition: mutex.h:79
pthread_mutex_t * native_handle_type
Return native_handle.
Definition: mutex.h:200
bool try_acquire(mutex &mutex)
Try acquire lock on given mutex.
Definition: mutex.h:103
The scoped locking pattern.
Definition: mutex.h:76
void release()
Release lock.
Definition: mutex.h:115
void acquire(mutex &mutex)
Acquire lock on given mutex.
Definition: mutex.h:93
Block of space aligned sufficiently to construct an array T with N elements.
Definition: aligned_space.h:33
void unlock()
Release lock.
Definition: mutex.h:181
scoped_lock(mutex &mutex)
Acquire lock on given mutex.
Definition: mutex.h:82
mutex()
Construct unacquired mutex.
Definition: mutex.h:43
bool try_lock()
Try acquiring lock (non-blocking)
Definition: mutex.h:165
void lock()
Acquire lock.
Definition: mutex.h:148
T * begin()
Pointer to beginning of array.
Definition: aligned_space.h:39
The namespace tbb contains all components of the library.
Definition: parallel_for.h:44
Wrapper around the platform&#39;s native reader-writer lock.
Definition: mutex.h:40