BRE12
spin_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_spin_mutex_H
22 #define __TBB_spin_mutex_H
23 
24 #include <cstddef>
25 #include <new>
26 #include "aligned_space.h"
27 #include "tbb_stddef.h"
28 #include "tbb_machine.h"
29 #include "tbb_profiling.h"
30 #include "internal/_mutex_padding.h"
31 
32 namespace tbb {
33 
35 
40 class spin_mutex : internal::mutex_copy_deprecated_and_disabled {
42  __TBB_atomic_flag flag;
43 
44 public:
46 
47  spin_mutex() : flag(0) {
48 #if TBB_USE_THREADING_TOOLS
50 #endif
51  }
52 
54  class scoped_lock : internal::no_copy {
55  private:
57  spin_mutex* my_mutex;
58 
60 
63  __TBB_Flag my_unlock_value;
64 
66  void __TBB_EXPORTED_METHOD internal_acquire( spin_mutex& m );
67 
69  bool __TBB_EXPORTED_METHOD internal_try_acquire( spin_mutex& m );
70 
72  void __TBB_EXPORTED_METHOD internal_release();
73 
74  friend class spin_mutex;
75 
76  public:
78  scoped_lock() : my_mutex(NULL), my_unlock_value(0) {}
79 
81  scoped_lock( spin_mutex& m ) : my_unlock_value(0) {
82  internal::suppress_unused_warning(my_unlock_value);
83 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
84  my_mutex=NULL;
85  internal_acquire(m);
86 #else
87  my_mutex=&m;
88  __TBB_LockByte(m.flag);
89 #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT*/
90  }
91 
93  void acquire( spin_mutex& m ) {
94 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
95  internal_acquire(m);
96 #else
97  my_mutex = &m;
98  __TBB_LockByte(m.flag);
99 #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT*/
100  }
101 
103 
104  bool try_acquire( spin_mutex& m ) {
105 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
106  return internal_try_acquire(m);
107 #else
108  bool result = __TBB_TryLockByte(m.flag);
109  if( result )
110  my_mutex = &m;
111  return result;
112 #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT*/
113  }
114 
116  void release() {
117 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
118  internal_release();
119 #else
120  __TBB_UnlockByte(my_mutex->flag);
121  my_mutex = NULL;
122 #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */
123  }
124 
127  if( my_mutex ) {
128 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
129  internal_release();
130 #else
131  __TBB_UnlockByte(my_mutex->flag);
132 #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */
133  }
134  }
135  };
136 
138  void __TBB_EXPORTED_METHOD internal_construct();
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_THREADING_TOOLS
151  new(tmp.begin()) scoped_lock(*this);
152 #else
153  __TBB_LockByte(flag);
154 #endif /* TBB_USE_THREADING_TOOLS*/
155  }
156 
158 
159  bool try_lock() {
160 #if TBB_USE_THREADING_TOOLS
162  return (new(tmp.begin()) scoped_lock)->internal_try_acquire(*this);
163 #else
164  return __TBB_TryLockByte(flag);
165 #endif /* TBB_USE_THREADING_TOOLS*/
166  }
167 
169  void unlock() {
170 #if TBB_USE_THREADING_TOOLS
172  scoped_lock& s = *tmp.begin();
173  s.my_mutex = this;
174  s.internal_release();
175 #else
176  __TBB_store_with_release(flag, 0);
177 #endif /* TBB_USE_THREADING_TOOLS */
178  }
179 
180  friend class scoped_lock;
181 }; // end of spin_mutex
182 
183 __TBB_DEFINE_PROFILING_SET_NAME(spin_mutex)
184 
185 } // namespace tbb
186 
187 #if ( __TBB_x86_32 || __TBB_x86_64 )
188 #include "internal/_x86_eliding_mutex_impl.h"
189 #endif
190 
191 namespace tbb {
193 
203 #if ( __TBB_x86_32 || __TBB_x86_64 )
205 #else
207 #endif
208 __TBB_DEFINE_PROFILING_SET_NAME(speculative_spin_mutex)
209 
210 } // namespace tbb
211 
212 #endif /* __TBB_spin_mutex_H */
scoped_lock(spin_mutex &m)
Construct and acquire lock on a mutex.
Definition: spin_mutex.h:81
interface7::internal::padded_mutex< spin_mutex, false > speculative_spin_mutex
A cross-platform spin mutex with speculative lock acquisition.
Definition: spin_mutex.h:206
~scoped_lock()
Destroy lock. If holding a lock, releases the lock first.
Definition: spin_mutex.h:126
void lock()
Acquire lock.
Definition: spin_mutex.h:148
void release()
Release lock.
Definition: spin_mutex.h:116
bool try_acquire(spin_mutex &m)
Try acquiring lock (non-blocking)
Definition: spin_mutex.h:104
bool try_lock()
Try acquiring lock (non-blocking)
Definition: spin_mutex.h:159
Block of space aligned sufficiently to construct an array T with N elements.
Definition: aligned_space.h:33
void __TBB_EXPORTED_METHOD internal_construct()
Internal constructor with ITT instrumentation.
Represents acquisition of a mutex.
Definition: spin_mutex.h:54
spin_mutex()
Construct unacquired lock.
Definition: spin_mutex.h:47
Definition: _mutex_padding.h:36
T * begin()
Pointer to beginning of array.
Definition: aligned_space.h:39
void acquire(spin_mutex &m)
Acquire lock.
Definition: spin_mutex.h:93
A lock that occupies a single byte.
Definition: spin_mutex.h:40
The namespace tbb contains all components of the library.
Definition: parallel_for.h:44
void unlock()
Release lock.
Definition: spin_mutex.h:169
scoped_lock()
Construct without acquiring a mutex.
Definition: spin_mutex.h:78