LIPH's C++ Codes
lock.h
Go to the documentation of this file.
1#ifndef LIPH_CONCURRENCY_LOCK_H_
2#define LIPH_CONCURRENCY_LOCK_H_
3
4#include <atomic>
5#include <mutex>
6#include <stdexcept>
7#include <thread>
8
9// spinlock
10// hierarchical_mutex
11
12namespace liph {
13
14class spinlock {
15public:
16 bool try_lock() noexcept { return !v_.test_and_set(std::memory_order_acquire); }
17
18 void lock() noexcept {
19 while (!try_lock()) {
20 std::this_thread::yield();
21 }
22 }
23
24 void unlock() noexcept { v_.clear(std::memory_order_release); }
25
26private:
27 std::atomic_flag v_ /* = ATOMIC_FLAG_INIT */;
28
29public:
31 private:
32 spinlock& sp_;
33
35 scoped_lock& operator=(scoped_lock const&);
36
37 public:
38 explicit scoped_lock(spinlock& sp) noexcept : sp_(sp) { sp.lock(); }
39
40 ~scoped_lock() { sp_.unlock(); }
41 };
42};
43
45public:
46 explicit hierarchical_mutex(unsigned long value) : hierarchy_value_(value), previous_hierarchy_value_(0) {}
47 void lock() {
48 check_for_hierarchy_violation();
49 mtx_.lock();
50 update_hierarchy_value();
51 }
52 void unlock() {
53 this_thread_hierarchy_value = previous_hierarchy_value_;
54 mtx_.unlock();
55 }
56 bool try_lock() {
57 check_for_hierarchy_violation();
58 if (!mtx_.try_lock()) return false;
59 update_hierarchy_value();
60 return true;
61 }
62
63private:
64 std::mutex mtx_;
65 unsigned long const hierarchy_value_;
66 unsigned long previous_hierarchy_value_;
67 static thread_local unsigned long this_thread_hierarchy_value;
68
69 void check_for_hierarchy_violation() {
70 if (this_thread_hierarchy_value <= hierarchy_value_) {
71 throw std::logic_error("mutex hierarchy violated");
72 }
73 }
74 void update_hierarchy_value() {
75 previous_hierarchy_value_ = this_thread_hierarchy_value;
76 this_thread_hierarchy_value = hierarchy_value_;
77 }
78};
79
80inline thread_local unsigned long hierarchical_mutex::this_thread_hierarchy_value(
81 std::numeric_limits<unsigned long>::max());
82
83template <class Mutex>
85public:
86 explicit unique_unlock(std::unique_lock<Mutex>& lock) : lock_(lock) { lock_.unlock(); }
87 ~unique_unlock() { lock_.lock(); }
88
89 unique_unlock(const unique_unlock&) = delete;
93
94private:
95 std::unique_lock<Mutex>& lock_;
96};
97
98} // namespace liph
99
100#endif // LIPH_CONCURRENCY_LOCK_H_
Definition: lock.h:44
void unlock()
Definition: lock.h:52
bool try_lock()
Definition: lock.h:56
void lock()
Definition: lock.h:47
hierarchical_mutex(unsigned long value)
Definition: lock.h:46
Definition: lock.h:30
~scoped_lock()
Definition: lock.h:40
scoped_lock(spinlock &sp) noexcept
Definition: lock.h:38
Definition: lock.h:14
void unlock() noexcept
Definition: lock.h:24
void lock() noexcept
Definition: lock.h:18
bool try_lock() noexcept
Definition: lock.h:16
Definition: lock.h:84
unique_unlock(const unique_unlock &)=delete
~unique_unlock()
Definition: lock.h:87
unique_unlock(std::unique_lock< Mutex > &lock)
Definition: lock.h:86
unique_unlock & operator=(const unique_unlock &)=delete
unique_unlock & operator=(unique_unlock &&)=delete
unique_unlock(unique_unlock &&)=delete
Definition: algorithm.h:10