join 1.0
lightweight network framework library
Loading...
Searching...
No Matches
futex.hpp
Go to the documentation of this file.
1
25#ifndef JOIN_CORE_FUTEX_HPP
26#define JOIN_CORE_FUTEX_HPP
27
28// libjoin.
29#include <join/mutex.hpp>
30
31// Linux.
32#include <sys/syscall.h>
33#include <linux/futex.h>
34#include <unistd.h>
35
36// C++.
37#include <atomic>
38
39namespace join
40{
44 class Futex
45 {
46 public:
50 Futex () noexcept
51 : _futex (0)
52 {
53 }
54
59 Futex (const Futex& other) = delete;
60
66 Futex& operator= (const Futex& other) = delete;
67
72 Futex (Futex&& other) = delete;
73
79 Futex& operator= (Futex&& other) = delete;
80
84 ~Futex () = default;
85
89 void lock () noexcept
90 {
91 uint32_t expected = 0;
92 if (_futex.compare_exchange_strong (expected, 1, std::memory_order_acquire, std::memory_order_relaxed))
93 {
94 return;
95 }
96
97 do
98 {
99 if (expected == 2 ||
100 _futex.compare_exchange_strong (expected, 2, std::memory_order_relaxed, std::memory_order_relaxed))
101 {
102 ::syscall (SYS_futex, reinterpret_cast<uint32_t*> (&_futex), FUTEX_WAIT_PRIVATE, 2, nullptr,
103 nullptr, 0);
104 }
105 expected = 0;
106 }
107 while (!_futex.compare_exchange_strong (expected, 2, std::memory_order_acquire, std::memory_order_relaxed));
108 }
109
114 bool tryLock () noexcept
115 {
116 uint32_t expected = 0;
117 return _futex.compare_exchange_strong (expected, 1, std::memory_order_acquire, std::memory_order_relaxed);
118 }
119
123 void unlock () noexcept
124 {
125 if (_futex.exchange (0, std::memory_order_release) == 2)
126 {
127 ::syscall (SYS_futex, reinterpret_cast<uint32_t*> (&_futex), FUTEX_WAKE_PRIVATE, 1, nullptr, nullptr,
128 0);
129 }
130 }
131
136 std::atomic_uint32_t* handle () noexcept
137 {
138 return &_futex;
139 }
140
141 private:
143 alignas (4) std::atomic_uint32_t _futex;
144 };
145
150 {
151 public:
155 SharedFutex () noexcept
156 : _futex (0)
157 {
158 }
159
164 SharedFutex (const SharedFutex& other) = delete;
165
171 SharedFutex& operator= (const SharedFutex& other) = delete;
172
177 SharedFutex (SharedFutex&& other) = delete;
178
185
189 ~SharedFutex () = default;
190
194 void lock () noexcept
195 {
196 uint32_t expected = 0;
197 if (_futex.compare_exchange_strong (expected, 1, std::memory_order_acquire, std::memory_order_relaxed))
198 {
199 return;
200 }
201
202 do
203 {
204 if (expected == 2 ||
205 _futex.compare_exchange_strong (expected, 2, std::memory_order_relaxed, std::memory_order_relaxed))
206 {
207 ::syscall (SYS_futex, reinterpret_cast<uint32_t*> (&_futex), FUTEX_WAIT, 2, nullptr, nullptr, 0);
208 }
209 expected = 0;
210 }
211 while (!_futex.compare_exchange_strong (expected, 2, std::memory_order_acquire, std::memory_order_relaxed));
212 }
213
218 bool tryLock () noexcept
219 {
220 uint32_t expected = 0;
221 return _futex.compare_exchange_strong (expected, 1, std::memory_order_acquire, std::memory_order_relaxed);
222 }
223
227 void unlock () noexcept
228 {
229 if (_futex.exchange (0, std::memory_order_release) == 2)
230 {
231 ::syscall (SYS_futex, reinterpret_cast<uint32_t*> (&_futex), FUTEX_WAKE, 1, nullptr, nullptr, 0);
232 }
233 }
234
239 std::atomic_uint32_t* handle () noexcept
240 {
241 return &_futex;
242 }
243
244 private:
246 alignas (4) std::atomic_uint32_t _futex;
247 };
248}
249
250#endif
Futex-based mutex for intra-process locking.
Definition futex.hpp:45
~Futex()=default
destructor.
Futex() noexcept
default constructor.
Definition futex.hpp:50
Futex(const Futex &other)=delete
copy constructor.
Futex(Futex &&other)=delete
move constructor.
void lock() noexcept
lock the futex, blocking until it becomes available.
Definition futex.hpp:89
void unlock() noexcept
unlock the futex, waking one waiter if any.
Definition futex.hpp:123
Futex & operator=(const Futex &other)=delete
copy assignment.
bool tryLock() noexcept
try to lock the futex without blocking.
Definition futex.hpp:114
std::atomic_uint32_t * handle() noexcept
get a pointer to the underlying futex word.
Definition futex.hpp:136
Futex-based mutex suitable for inter-process locking via shared memory.
Definition futex.hpp:150
std::atomic_uint32_t * handle() noexcept
get a pointer to the underlying futex word.
Definition futex.hpp:239
SharedFutex(const SharedFutex &other)=delete
copy constructor.
SharedFutex & operator=(const SharedFutex &other)=delete
copy assignment.
SharedFutex(SharedFutex &&other)=delete
move constructor.
bool tryLock() noexcept
try to lock the futex without blocking.
Definition futex.hpp:218
void unlock() noexcept
unlock the futex, waking one waiter if any.
Definition futex.hpp:227
~SharedFutex()=default
destructor.
void lock() noexcept
lock the futex, blocking until it becomes available.
Definition futex.hpp:194
SharedFutex() noexcept
default constructor.
Definition futex.hpp:155
Definition acceptor.hpp:32