Intel(R) Threading Building Blocks Doxygen Documentation  version 4.2.3
spin_rw_mutex.h
Go to the documentation of this file.
1 /*
2  Copyright (c) 2005-2019 Intel Corporation
3 
4  Licensed under the Apache License, Version 2.0 (the "License");
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7 
8  http://www.apache.org/licenses/LICENSE-2.0
9 
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15 
16 
17 
18 
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"
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 
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 #endif
94  public:
96 
97  scoped_lock() : mutex(NULL), is_writer(false) {}
98 
100  scoped_lock( spin_rw_mutex& m, bool write = true ) : mutex(NULL) {
101  acquire(m, write);
102  }
103 
106  if( mutex ) release();
107  }
108 
110  void acquire( spin_rw_mutex& m, bool write = true ) {
111  __TBB_ASSERT( !mutex, "holding mutex already" );
112  is_writer = write;
113  mutex = &m;
114  if( write ) mutex->internal_acquire_writer();
115  else mutex->internal_acquire_reader();
116  }
117 
119 
121  __TBB_ASSERT( mutex, "mutex is not acquired" );
122  __TBB_ASSERT( !is_writer, "not a reader" );
123  is_writer = true;
124  return mutex->internal_upgrade();
125  }
126 
128  void release() {
129  __TBB_ASSERT( mutex, "mutex is not acquired" );
130  spin_rw_mutex *m = mutex;
131  mutex = NULL;
132 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
133  if( is_writer ) m->internal_release_writer();
134  else m->internal_release_reader();
135 #else
136  if( is_writer ) __TBB_AtomicAND( &m->state, READERS );
137  else __TBB_FetchAndAddWrelease( &m->state, -(intptr_t)ONE_READER);
138 #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */
139  }
140 
143  __TBB_ASSERT( mutex, "mutex is not acquired" );
144  __TBB_ASSERT( is_writer, "not a writer" );
145 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
146  mutex->internal_downgrade();
147 #else
148  __TBB_FetchAndAddW( &mutex->state, ((intptr_t)ONE_READER-WRITER));
149 #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */
150  is_writer = false;
151  return true;
152  }
153 
155  bool try_acquire( spin_rw_mutex& m, bool write = true ) {
156  __TBB_ASSERT( !mutex, "holding mutex already" );
157  bool result;
158  is_writer = write;
159  result = write? m.internal_try_acquire_writer()
161  if( result )
162  mutex = &m;
163  return result;
164  }
165 
166  protected:
167 
169  spin_rw_mutex* mutex;
170 
172 
173  bool is_writer;
174  };
175 
176  // Mutex traits
177  static const bool is_rw_mutex = true;
178  static const bool is_recursive_mutex = false;
179  static const bool is_fair_mutex = false;
180 
181  // ISO C++0x compatibility methods
182 
184  void lock() {internal_acquire_writer();}
185 
187 
188  bool try_lock() {return internal_try_acquire_writer();}
189 
191  void unlock() {
192 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
193  if( state&WRITER ) internal_release_writer();
194  else internal_release_reader();
195 #else
196  if( state&WRITER ) __TBB_AtomicAND( &state, READERS );
197  else __TBB_FetchAndAddWrelease( &state, -(intptr_t)ONE_READER);
198 #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */
199  }
200 
201  // Methods for reader locks that resemble ISO C++0x compatibility methods.
202 
204  void lock_read() {internal_acquire_reader();}
205 
207 
208  bool try_lock_read() {return internal_try_acquire_reader();}
209 
210 protected:
211  typedef intptr_t state_t;
212  static const state_t WRITER = 1;
213  static const state_t WRITER_PENDING = 2;
214  static const state_t READERS = ~(WRITER | WRITER_PENDING);
215  static const state_t ONE_READER = 4;
216  static const state_t BUSY = WRITER | READERS;
218 
221  state_t state;
222 
223 private:
224  void __TBB_EXPORTED_METHOD internal_construct();
225 };
226 
227 __TBB_DEFINE_PROFILING_SET_NAME(spin_rw_mutex)
228 
229 } // namespace tbb
230 
231 #if __TBB_TSX_AVAILABLE
233 #endif
234 
235 namespace tbb {
236 namespace interface8 {
238 
246 #if __TBB_TSX_AVAILABLE
248 #else
250 #endif
251 } // namespace interface8
252 
255 } // namespace tbb
256 #endif /* __TBB_spin_rw_mutex_H */
state_t state
State of lock.
bool try_lock()
Try acquiring writer lock (non-blocking)
spin_rw_mutex * mutex
The pointer to the current mutex that is held, or NULL if no mutex is held.
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
void lock_read()
Acquire reader lock.
#define __TBB_FetchAndAddWrelease(P, V)
Definition: tbb_machine.h:316
void __TBB_AtomicAND(volatile void *operand, uintptr_t addend)
Definition: tbb_machine.h:895
~scoped_lock()
Release lock (if lock is held).
bool downgrade_to_reader()
Downgrade writer to become a reader.
Acquire.
Definition: atomic.h:47
The scoped locking pattern.
Definition: spin_rw_mutex.h:90
scoped_lock()
Construct lock that has not acquired a mutex.
Definition: spin_rw_mutex.h:97
#define __TBB_EXPORTED_METHOD
Definition: tbb_stddef.h:102
bool try_acquire(spin_rw_mutex &m, bool write=true)
Try acquire lock on given mutex.
bool __TBB_EXPORTED_METHOD internal_try_acquire_reader()
Internal try_acquire read lock.
The graph class.
void acquire(spin_rw_mutex &m, bool write=true)
Acquire lock on given mutex.
spin_rw_mutex_v3()
Construct unacquired mutex.
Definition: spin_rw_mutex.h:74
#define __TBB_DEFINE_PROFILING_SET_NAME(sync_object_type)
void lock()
Acquire writer lock.
void unlock()
Release lock.
spin_rw_mutex_v3 spin_rw_mutex
Definition: spin_rw_mutex.h:37
bool try_lock_read()
Try acquiring reader lock (non-blocking)
void __TBB_EXPORTED_METHOD internal_release_writer()
Out of line code for releasing a write lock.
Wrapper around the platform's native lock.
Definition: mutex.h:39
bool is_writer
If mutex!=NULL, then is_writer is true if holding a writer lock, false if holding a reader lock...
void __TBB_EXPORTED_METHOD internal_release_reader()
Internal release read lock.
bool upgrade_to_writer()
Upgrade reader to become a writer.
scoped_lock(spin_rw_mutex &m, bool write=true)
Acquire lock on given mutex.
Release.
Definition: atomic.h:49
bool __TBB_EXPORTED_METHOD internal_try_acquire_writer()
Internal try_acquire write lock.
interface7::internal::padded_mutex< tbb::spin_rw_mutex, true > speculative_spin_rw_mutex
A cross-platform spin reader/writer mutex with speculative lock acquisition.
Fast, unfair, spinning reader-writer lock with backoff and writer-preference.
Definition: spin_rw_mutex.h:42

Copyright © 2005-2019 Intel Corporation. All Rights Reserved.

Intel, Pentium, Intel Xeon, Itanium, Intel XScale and VTune are registered trademarks or trademarks of Intel Corporation or its subsidiaries in the United States and other countries.

* Other names and brands may be claimed as the property of others.