BRE12
spin_rw_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_rw_mutex_H
22 #define __TBB_spin_rw_mutex_H
23 
24 #include "tbb_stddef.h"
25 #include "tbb_machine.h"
26 #include "tbb_profiling.h"
27 #include "internal/_mutex_padding.h"
28 
29 namespace tbb {
30 
31 #if __TBB_TSX_AVAILABLE
32 namespace interface8 { namespace internal {
33  class x86_rtm_rw_mutex;
34 }}
35 #endif
36 
37 class spin_rw_mutex_v3;
38 typedef spin_rw_mutex_v3 spin_rw_mutex;
39 
41 
42 class spin_rw_mutex_v3 : internal::mutex_copy_deprecated_and_disabled {
44 
46  bool __TBB_EXPORTED_METHOD internal_acquire_writer();
47 
49 
50  void __TBB_EXPORTED_METHOD internal_release_writer();
51 
53  void __TBB_EXPORTED_METHOD internal_acquire_reader();
54 
56  bool __TBB_EXPORTED_METHOD internal_upgrade();
57 
59 
60  void __TBB_EXPORTED_METHOD internal_downgrade();
61 
63  void __TBB_EXPORTED_METHOD internal_release_reader();
64 
66  bool __TBB_EXPORTED_METHOD internal_try_acquire_writer();
67 
69  bool __TBB_EXPORTED_METHOD internal_try_acquire_reader();
70 
72 public:
74  spin_rw_mutex_v3() : state(0) {
75 #if TBB_USE_THREADING_TOOLS
76  internal_construct();
77 #endif
78  }
79 
80 #if TBB_USE_ASSERT
81  ~spin_rw_mutex_v3() {
83  __TBB_ASSERT( !state, "destruction of an acquired mutex");
84  };
85 #endif /* TBB_USE_ASSERT */
86 
88 
90  class scoped_lock : internal::no_copy {
91 #if __TBB_TSX_AVAILABLE
92  friend class tbb::interface8::internal::x86_rtm_rw_mutex;
93  // helper methods for x86_rtm_rw_mutex
94  spin_rw_mutex *internal_get_mutex() const { return mutex; }
95  void internal_set_mutex(spin_rw_mutex* m) { mutex = m; }
96 #endif
97  public:
99 
100  scoped_lock() : mutex(NULL), is_writer(false) {}
101 
103  scoped_lock( spin_rw_mutex& m, bool write = true ) : mutex(NULL) {
104  acquire(m, write);
105  }
106 
109  if( mutex ) release();
110  }
111 
113  void acquire( spin_rw_mutex& m, bool write = true ) {
114  __TBB_ASSERT( !mutex, "holding mutex already" );
115  is_writer = write;
116  mutex = &m;
117  if( write ) mutex->internal_acquire_writer();
118  else mutex->internal_acquire_reader();
119  }
120 
122 
124  __TBB_ASSERT( mutex, "lock is not acquired" );
125  __TBB_ASSERT( !is_writer, "not a reader" );
126  is_writer = true;
127  return mutex->internal_upgrade();
128  }
129 
131  void release() {
132  __TBB_ASSERT( mutex, "lock is not acquired" );
133  spin_rw_mutex *m = mutex;
134  mutex = NULL;
135 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
136  if( is_writer ) m->internal_release_writer();
137  else m->internal_release_reader();
138 #else
139  if( is_writer ) __TBB_AtomicAND( &m->state, READERS );
140  else __TBB_FetchAndAddWrelease( &m->state, -(intptr_t)ONE_READER);
141 #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */
142  }
143 
146  __TBB_ASSERT( mutex, "lock is not acquired" );
147  __TBB_ASSERT( is_writer, "not a writer" );
148 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
149  mutex->internal_downgrade();
150 #else
151  __TBB_FetchAndAddW( &mutex->state, ((intptr_t)ONE_READER-WRITER));
152 #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */
153  is_writer = false;
154  return true;
155  }
156 
158  bool try_acquire( spin_rw_mutex& m, bool write = true ) {
159  __TBB_ASSERT( !mutex, "holding mutex already" );
160  bool result;
161  is_writer = write;
162  result = write? m.internal_try_acquire_writer()
163  : m.internal_try_acquire_reader();
164  if( result )
165  mutex = &m;
166  return result;
167  }
168 
169  protected:
170 
172  spin_rw_mutex* mutex;
173 
175 
176  bool is_writer;
177  };
178 
179  // Mutex traits
180  static const bool is_rw_mutex = true;
181  static const bool is_recursive_mutex = false;
182  static const bool is_fair_mutex = false;
183 
184  // ISO C++0x compatibility methods
185 
187  void lock() {internal_acquire_writer();}
188 
190 
191  bool try_lock() {return internal_try_acquire_writer();}
192 
194  void unlock() {
195 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
196  if( state&WRITER ) internal_release_writer();
197  else internal_release_reader();
198 #else
199  if( state&WRITER ) __TBB_AtomicAND( &state, READERS );
200  else __TBB_FetchAndAddWrelease( &state, -(intptr_t)ONE_READER);
201 #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */
202  }
203 
204  // Methods for reader locks that resemble ISO C++0x compatibility methods.
205 
207  void lock_read() {internal_acquire_reader();}
208 
210 
211  bool try_lock_read() {return internal_try_acquire_reader();}
212 
213 protected:
214  typedef intptr_t state_t;
215  static const state_t WRITER = 1;
216  static const state_t WRITER_PENDING = 2;
217  static const state_t READERS = ~(WRITER | WRITER_PENDING);
218  static const state_t ONE_READER = 4;
219  static const state_t BUSY = WRITER | READERS;
221 
224  state_t state;
225 
226 private:
227  void __TBB_EXPORTED_METHOD internal_construct();
228 };
229 
230 __TBB_DEFINE_PROFILING_SET_NAME(spin_rw_mutex)
231 
232 } // namespace tbb
233 
234 #if __TBB_TSX_AVAILABLE
235 #include "internal/_x86_rtm_rw_mutex_impl.h"
236 #endif
237 
238 namespace tbb {
239 namespace interface8 {
241 
249 #if __TBB_TSX_AVAILABLE
251 #else
253 #endif
254 } // namespace interface8
255 
257 __TBB_DEFINE_PROFILING_SET_NAME(speculative_spin_rw_mutex)
258 } // namespace tbb
259 #endif /* __TBB_spin_rw_mutex_H */
bool upgrade_to_writer()
Upgrade reader to become a writer.
Definition: spin_rw_mutex.h:123
~scoped_lock()
Release lock (if lock is held).
Definition: spin_rw_mutex.h:108
void lock_read()
Acquire reader lock.
Definition: spin_rw_mutex.h:207
spin_rw_mutex * mutex
The pointer to the current mutex that is held, or NULL if no mutex is held.
Definition: spin_rw_mutex.h:172
void unlock()
Release lock.
Definition: spin_rw_mutex.h:194
Fast, unfair, spinning reader-writer lock with backoff and writer-preference.
Definition: spin_rw_mutex.h:42
Acquire.
Definition: atomic.h:47
scoped_lock()
Construct lock that has not acquired a mutex.
Definition: spin_rw_mutex.h:100
interface7::internal::padded_mutex< tbb::spin_rw_mutex, true > speculative_spin_rw_mutex
A cross-platform spin reader/writer mutex with speculative lock acquisition.
Definition: spin_rw_mutex.h:252
bool is_writer
If mutex!=NULL, then is_writer is true if holding a writer lock, false if holding a reader lock...
Definition: spin_rw_mutex.h:176
spin_rw_mutex_v3()
Construct unacquired mutex.
Definition: spin_rw_mutex.h:74
The scoped locking pattern.
Definition: spin_rw_mutex.h:90
void acquire(spin_rw_mutex &m, bool write=true)
Acquire lock on given mutex.
Definition: spin_rw_mutex.h:113
void lock()
Acquire writer lock.
Definition: spin_rw_mutex.h:187
bool try_lock()
Try acquiring writer lock (non-blocking)
Definition: spin_rw_mutex.h:191
Definition: _mutex_padding.h:36
void release()
Release lock.
Definition: spin_rw_mutex.h:131
Definition: _flow_graph_async_msg_impl.h:32
Release.
Definition: atomic.h:49
The namespace tbb contains all components of the library.
Definition: parallel_for.h:44
state_t state
State of lock.
Definition: spin_rw_mutex.h:224
scoped_lock(spin_rw_mutex &m, bool write=true)
Acquire lock on given mutex.
Definition: spin_rw_mutex.h:103
bool try_acquire(spin_rw_mutex &m, bool write=true)
Try acquire lock on given mutex.
Definition: spin_rw_mutex.h:158
bool try_lock_read()
Try acquiring reader lock (non-blocking)
Definition: spin_rw_mutex.h:211
bool downgrade_to_reader()
Downgrade writer to become a reader.
Definition: spin_rw_mutex.h:145
Wrapper around the platform&#39;s native reader-writer lock.
Definition: mutex.h:40