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-2020 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 
33 class spin_rw_mutex_v3;
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
78  ~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 */
void __TBB_AtomicAND(volatile void *operand, uintptr_t addend)
Definition: tbb_machine.h:888
#define __TBB_FetchAndAddWrelease(P, V)
Definition: tbb_machine.h:309
#define __TBB_DEFINE_PROFILING_SET_NAME(sync_object_type)
#define __TBB_EXPORTED_METHOD
Definition: tbb_stddef.h:98
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:165
interface7::internal::padded_mutex< tbb::spin_rw_mutex, true > speculative_spin_rw_mutex
A cross-platform spin reader/writer mutex with speculative lock acquisition.
The graph class.
spin_rw_mutex_v3 spin_rw_mutex
Definition: spin_rw_mutex.h:33
Fast, unfair, spinning reader-writer lock with backoff and writer-preference.
Definition: spin_rw_mutex.h:38
bool __TBB_EXPORTED_METHOD internal_acquire_writer()
Internal acquire write lock.
bool __TBB_EXPORTED_METHOD internal_try_acquire_writer()
Internal try_acquire write lock.
void lock()
Acquire writer lock.
static const state_t WRITER_PENDING
static const state_t BUSY
static const state_t READERS
bool __TBB_EXPORTED_METHOD internal_try_acquire_reader()
Internal try_acquire read lock.
static const bool is_recursive_mutex
void __TBB_EXPORTED_METHOD internal_construct()
void __TBB_EXPORTED_METHOD internal_downgrade()
Out of line code for downgrading a writer to a reader.
void lock_read()
Acquire reader lock.
state_t state
State of lock.
static const state_t WRITER
void unlock()
Release lock.
void __TBB_EXPORTED_METHOD internal_release_reader()
Internal release read lock.
bool try_lock()
Try acquiring writer lock (non-blocking)
bool __TBB_EXPORTED_METHOD internal_upgrade()
Internal upgrade reader to become a writer.
void __TBB_EXPORTED_METHOD internal_acquire_reader()
Internal acquire read lock.
bool try_lock_read()
Try acquiring reader lock (non-blocking)
spin_rw_mutex_v3()
Construct unacquired mutex.
Definition: spin_rw_mutex.h:70
void __TBB_EXPORTED_METHOD internal_release_writer()
Out of line code for releasing a write lock.
static const bool is_rw_mutex
static const state_t ONE_READER
static const bool is_fair_mutex
The scoped locking pattern.
Definition: spin_rw_mutex.h:86
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
~scoped_lock()
Release lock (if lock is held).
void acquire(spin_rw_mutex &m, bool write=true)
Acquire lock on given mutex.
spin_rw_mutex * mutex
The pointer to the current mutex that is held, or NULL if no mutex is held.
bool downgrade_to_reader()
Downgrade writer to become a reader.
bool try_acquire(spin_rw_mutex &m, bool write=true)
Try acquire lock on given mutex.
bool is_writer
If mutex!=NULL, then is_writer is true if holding a writer lock, false if holding a reader lock.
bool upgrade_to_writer()
Upgrade reader to become a writer.
Base class for types that should not be copied or assigned.
Definition: tbb_stddef.h:330

Copyright © 2005-2020 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.