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 #ifndef __TBB_spin_rw_mutex_H
18 #define __TBB_spin_rw_mutex_H
19 
20 #include "tbb_stddef.h"
21 #include "tbb_machine.h"
22 #include "tbb_profiling.h"
24 
25 namespace tbb {
26 
27 #if __TBB_TSX_AVAILABLE
28 namespace interface8 { namespace internal {
29  class x86_rtm_rw_mutex;
30 }}
31 #endif
32 
35 
37 
40 
43 
45 
47 
50 
53 
55 
57 
60 
63 
66 
68 public:
71 #if TBB_USE_THREADING_TOOLS
73 #endif
74  }
75 
76 #if TBB_USE_ASSERT
77  ~spin_rw_mutex_v3() {
79  __TBB_ASSERT( !state, "destruction of an acquired mutex");
80  };
81 #endif /* TBB_USE_ASSERT */
82 
84 
87 #if __TBB_TSX_AVAILABLE
88  friend class tbb::interface8::internal::x86_rtm_rw_mutex;
89 #endif
90  public:
92 
93  scoped_lock() : mutex(NULL), is_writer(false) {}
94 
96  scoped_lock( spin_rw_mutex& m, bool write = true ) : mutex(NULL) {
97  acquire(m, write);
98  }
99 
102  if( mutex ) release();
103  }
104 
106  void acquire( spin_rw_mutex& m, bool write = true ) {
107  __TBB_ASSERT( !mutex, "holding mutex already" );
108  is_writer = write;
109  mutex = &m;
110  if( write ) mutex->internal_acquire_writer();
112  }
113 
115 
117  __TBB_ASSERT( mutex, "mutex is not acquired" );
118  if (is_writer) return true; // Already a writer
119  is_writer = true;
120  return mutex->internal_upgrade();
121  }
122 
124  void release() {
125  __TBB_ASSERT( mutex, "mutex is not acquired" );
126  spin_rw_mutex *m = mutex;
127  mutex = NULL;
128 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
130  else m->internal_release_reader();
131 #else
132  if( is_writer ) __TBB_AtomicAND( &m->state, READERS );
133  else __TBB_FetchAndAddWrelease( &m->state, -(intptr_t)ONE_READER);
134 #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */
135  }
136 
139  __TBB_ASSERT( mutex, "mutex is not acquired" );
140  if (!is_writer) return true; // Already a reader
141 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
143 #else
144  __TBB_FetchAndAddW( &mutex->state, ((intptr_t)ONE_READER-WRITER));
145 #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */
146  is_writer = false;
147  return true;
148  }
149 
151  bool try_acquire( spin_rw_mutex& m, bool write = true ) {
152  __TBB_ASSERT( !mutex, "holding mutex already" );
153  bool result;
154  is_writer = write;
155  result = write? m.internal_try_acquire_writer()
157  if( result )
158  mutex = &m;
159  return result;
160  }
161 
162  protected:
163 
166 
168 
169  bool is_writer;
170  };
171 
172  // Mutex traits
173  static const bool is_rw_mutex = true;
174  static const bool is_recursive_mutex = false;
175  static const bool is_fair_mutex = false;
176 
177  // ISO C++0x compatibility methods
178 
181 
183 
185 
187  void unlock() {
188 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
191 #else
193  else __TBB_FetchAndAddWrelease( &state, -(intptr_t)ONE_READER);
194 #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */
195  }
196 
197  // Methods for reader locks that resemble ISO C++0x compatibility methods.
198 
201 
203 
205 
206 protected:
207  typedef intptr_t state_t;
208  static const state_t WRITER = 1;
209  static const state_t WRITER_PENDING = 2;
210  static const state_t READERS = ~(WRITER | WRITER_PENDING);
211  static const state_t ONE_READER = 4;
212  static const state_t BUSY = WRITER | READERS;
214 
218 
219 private:
221 };
222 
224 
225 } // namespace tbb
226 
227 #if __TBB_TSX_AVAILABLE
229 #endif
230 
231 namespace tbb {
232 namespace interface8 {
234 
242 #if __TBB_TSX_AVAILABLE
244 #else
246 #endif
247 } // namespace interface8
248 
251 } // namespace tbb
252 #endif /* __TBB_spin_rw_mutex_H */
bool __TBB_EXPORTED_METHOD internal_acquire_writer()
Internal acquire write lock.
void __TBB_EXPORTED_METHOD internal_acquire_reader()
Internal acquire read lock.
bool try_lock_read()
Try acquiring reader lock (non-blocking)
#define __TBB_DEFINE_PROFILING_SET_NAME(sync_object_type)
bool __TBB_EXPORTED_METHOD internal_upgrade()
Internal upgrade reader to become a writer.
~scoped_lock()
Release lock (if lock is held).
spin_rw_mutex * mutex
The pointer to the current mutex that is held, or NULL if no mutex is held.
static const state_t READERS
spin_rw_mutex_v3 spin_rw_mutex
Definition: spin_rw_mutex.h:33
void __TBB_EXPORTED_METHOD internal_downgrade()
Out of line code for downgrading a writer to a reader.
void __TBB_EXPORTED_METHOD internal_construct()
The graph class.
bool __TBB_EXPORTED_METHOD internal_try_acquire_reader()
Internal try_acquire read lock.
static const state_t ONE_READER
static const bool is_fair_mutex
static const state_t BUSY
Fast, unfair, spinning reader-writer lock with backoff and writer-preference.
Definition: spin_rw_mutex.h:38
void lock_read()
Acquire reader lock.
static const state_t WRITER
void __TBB_AtomicAND(volatile void *operand, uintptr_t addend)
Definition: tbb_machine.h:888
spin_rw_mutex_v3()
Construct unacquired mutex.
Definition: spin_rw_mutex.h:70
scoped_lock(spin_rw_mutex &m, bool write=true)
Acquire lock on given mutex.
Definition: spin_rw_mutex.h:96
scoped_lock()
Construct lock that has not acquired a mutex.
Definition: spin_rw_mutex.h:93
interface7::internal::padded_mutex< tbb::spin_rw_mutex, true > speculative_spin_rw_mutex
A cross-platform spin reader/writer mutex with speculative lock acquisition.
static const bool is_recursive_mutex
state_t state
State of lock.
bool try_acquire(spin_rw_mutex &m, bool write=true)
Try acquire lock on given mutex.
static const state_t WRITER_PENDING
Base class for types that should not be copied or assigned.
Definition: tbb_stddef.h:330
bool is_writer
If mutex!=NULL, then is_writer is true if holding a writer lock, false if holding a reader lock.
static const bool is_rw_mutex
bool __TBB_EXPORTED_METHOD internal_try_acquire_writer()
Internal try_acquire write lock.
void __TBB_EXPORTED_METHOD internal_release_writer()
Out of line code for releasing a write lock.
The scoped locking pattern.
Definition: spin_rw_mutex.h:86
#define __TBB_EXPORTED_METHOD
Definition: tbb_stddef.h:98
void unlock()
Release lock.
#define __TBB_FetchAndAddWrelease(P, V)
Definition: tbb_machine.h:309
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:165
void lock()
Acquire writer lock.
bool upgrade_to_writer()
Upgrade reader to become a writer.
bool try_lock()
Try acquiring writer lock (non-blocking)
void __TBB_EXPORTED_METHOD internal_release_reader()
Internal release read lock.
bool downgrade_to_reader()
Downgrade writer to become a reader.
void acquire(spin_rw_mutex &m, bool write=true)
Acquire lock on given mutex.

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.