libUTL++
RWlockLF.h
1 #pragma once
2 
4 
5 #include <libutl/host_thread.h>
6 #include <libutl/NamedObjectMI.h>
7 
9 
10 UTL_NS_BEGIN;
11 
13 
14 class Mutex;
15 
17 // RWlockLF ////////////////////////////////////////////////////////////////////////////////////////
19 
33 
35 class RWlockLF : public Object, public NamedObjectMI
36 {
39 
40 public:
42  bool haveWriteLock() const;
43 
48  void
49  lock(uint_t mode)
50  {
51  (mode == io_rd) ? rdlock() : wrlock();
52  }
53 
55  void rdlock();
56 
58  void wrlock();
59 
61  void unlock();
62 
67  bool
69  {
70  return (mode == io_rd) ? tryrdlock() : trywrlock();
71  }
72 
77  bool tryrdlock();
78 
83  bool trywrlock();
84 
85 private:
86  void init();
87 
88  void
89  deInit()
90  {
91  }
92 
93  thread_handle_t
94  owner() const
95  {
96  return _writeLockOwner.load(std::memory_order_relaxed);
97  }
98 
99 private:
100  char pad1[UTL_CACHE_LINE_SIZE - sizeof(void*)];
101  std::atomic<thread_handle_t> _writeLockOwner;
102  size_t _depth;
103  char pad2[UTL_CACHE_LINE_SIZE - sizeof(size_t)];
104  std::atomic_size_t _numActive;
105  char pad3[UTL_CACHE_LINE_SIZE - sizeof(size_t)];
106 };
107 
109 // RWlockLFguard ///////////////////////////////////////////////////////////////////////////////////
111 
119 
122 {
123 public:
126  : _locked(false)
127  , _rwlock(nullptr)
128  {
129  }
130 
137  : _locked(false)
138  , _rwlock(rwlock)
139  {
140  _lock(mode);
141  }
142 
145  {
146  unlock();
147  }
148 
154  void
155  lock(RWlockLF* rwlock, uint_t mode)
156  {
157  unlock();
158  _rwlock = rwlock;
159  _lock(mode);
160  }
161 
166  void
167  lock(uint_t mode)
168  {
169  (mode == io_rd) ? rdlock() : wrlock();
170  }
171 
176  void
177  rdlock(RWlockLF* rwlock)
178  {
179  unlock();
180  _rwlock = rwlock;
181  _rdlock();
182  }
183 
188  void
189  wrlock(RWlockLF* rwlock)
190  {
191  unlock();
192  _rwlock = rwlock;
193  _wrlock();
194  }
195 
197  void
199  {
200  unlock();
201  _rdlock();
202  }
203 
205  void
207  {
208  unlock();
209  _wrlock();
210  }
211 
218  bool
219  trylock(RWlockLF* rwlock, uint_t mode)
220  {
221  unlock();
222  _rwlock = rwlock;
223  return _trylock(mode);
224  }
225 
231  bool
233  {
234  return (mode == io_rd) ? tryrdlock() : trywrlock();
235  }
236 
242  bool
244  {
245  unlock();
246  _rwlock = rwlock;
247  return _tryrdlock();
248  }
249 
255  bool
257  {
258  unlock();
259  _rwlock = rwlock;
260  return _trywrlock();
261  }
262 
267  bool
269  {
270  unlock();
271  return _tryrdlock();
272  }
273 
278  bool
280  {
281  unlock();
282  return _trywrlock();
283  }
284 
286  inline void
288  {
289  if (_locked) _unlock();
290  }
291 
292 private:
293  void
294  _lock(uint_t mode)
295  {
296  (mode == io_rd) ? _rdlock() : _wrlock();
297  }
298 
299  void
300  _rdlock()
301  {
302  ASSERTD(_rwlock != nullptr);
303  ASSERTD(!_locked);
304  _rwlock->rdlock();
305  _locked = true;
306  }
307 
308  void
309  _wrlock()
310  {
311  ASSERTD(_rwlock != nullptr);
312  ASSERTD(!_locked);
313  _rwlock->wrlock();
314  _locked = true;
315  }
316 
317  bool
318  _trylock(uint_t mode)
319  {
320  return (mode == io_rd) ? _tryrdlock() : _trywrlock();
321  }
322 
323  bool
324  _tryrdlock()
325  {
326  ASSERTD(_rwlock != nullptr);
327  ASSERTD(!_locked);
328  if (_rwlock->tryrdlock()) _locked = true;
329  return _locked;
330  }
331 
332  bool
333  _trywrlock()
334  {
335  ASSERTD(_rwlock != nullptr);
336  ASSERTD(!_locked);
337  if (_rwlock->trywrlock()) _locked = true;
338  return _locked;
339  }
340 
341  void
342  _unlock()
343  {
344  ASSERTD(_rwlock != nullptr);
345  ASSERTD(_locked);
346  _rwlock->unlock();
347  _locked = false;
348  }
349 
350 private:
351  bool _locked;
352  RWlockLF* _rwlock;
353 };
354 
356 
357 UTL_NS_END;
Named object mix-in.
Definition: NamedObjectMI.h:24
void deInit()
De-initialize UTL++.
void lock(uint_t mode)
Acquire read- or write-lock.
Definition: RWlockLF.h:167
#define UTL_CLASS_DECL(DC, BC)
Declaration of standard UTL++ functionality for a non-template class.
Definition: macros.h:688
void lock(uint_t mode)
Acquire read- or write-lock.
Definition: RWlockLF.h:49
Acquire/release a RWlockLF RAII-style.
Definition: RWlockLF.h:121
void wrlock()
Acquire write-lock.
Definition: RWlockLF.h:206
RWlockLFguard()
Default constructor.
Definition: RWlockLF.h:125
read
Definition: util.h:58
bool trywrlock(RWlockLF *rwlock)
Try to acquire write-lock (without blocking).
Definition: RWlockLF.h:256
void lock(RWlockLF *rwlock, uint_t mode)
Acquire read- or write-lock.
Definition: RWlockLF.h:155
bool trywrlock()
Try to acquire write-lock (without blocking).
Definition: RWlockLF.h:279
~RWlockLFguard()
Destructor.
Definition: RWlockLF.h:144
bool trylock(RWlockLF *rwlock, uint_t mode)
Try to acquire read- or write-lock (without blocking).
Definition: RWlockLF.h:219
RWlockLFguard(RWlockLF *rwlock, uint_t mode)
Constructor.
Definition: RWlockLF.h:136
Read/write lock (lock-free implementation).
Definition: RWlockLF.h:35
unsigned int uint_t
Unsigned integer.
Definition: types.h:59
void rdlock()
Acquire read-lock.
Definition: RWlockLF.h:198
void wrlock(RWlockLF *rwlock)
Acquire write-lock.
Definition: RWlockLF.h:189
bool tryrdlock(RWlockLF *rwlock)
Try to acquire read-lock (without blocking).
Definition: RWlockLF.h:243
bool tryrdlock()
Try to acquire read-lock (without blocking).
Definition: RWlockLF.h:268
bool trylock(uint_t mode)
Try to acquire read- or write-lock (without blocking).
Definition: RWlockLF.h:232
#define UTL_CLASS_NO_COPY
Declare that a class cannot do copy().
Definition: macros.h:358
void unlock()
Release the lock.
Definition: RWlockLF.h:287
Root of UTL++ class hierarchy.
Definition: Object.h:52
bool trylock(uint_t mode)
Try to acquire read- or write-lock (without blocking).
Definition: RWlockLF.h:68
void init()
Initialize UTL++.
#define ASSERTD
Do an assertion in DEBUG mode only.
void rdlock(RWlockLF *rwlock)
Acquire read-lock.
Definition: RWlockLF.h:177