cpp-ipc/include/rw_lock.h
2018-12-12 09:54:08 +08:00

50 lines
1.1 KiB
C++

#pragma once
#include <atomic>
#include <thread>
#include <limits>
namespace ipc {
class rw_lock {
std::atomic_size_t lc_ { 0 };
enum : std::size_t {
w_flag = std::numeric_limits<std::size_t>::max()
};
public:
void r_lock(void) {
while(1) {
std::size_t old = lc_.load(std::memory_order_relaxed);
std::size_t unlocked = old + 1;
if (unlocked &&
lc_.compare_exchange_weak(old, unlocked, std::memory_order_acq_rel)) {
break;
}
std::this_thread::yield();
std::atomic_thread_fence(std::memory_order_acquire);
}
}
void r_unlock(void) {
lc_.fetch_sub(1, std::memory_order_release);
}
void w_lock(void) {
while (1) {
std::size_t expected = 0;
if (lc_.compare_exchange_weak(expected, w_flag, std::memory_order_acq_rel)) {
break;
}
std::this_thread::yield();
}
}
void w_unlock(void) {
lc_.store(0, std::memory_order_release);
}
};
} // namespace ipc