put rw_lock to a single header file

This commit is contained in:
mutouyun 2018-12-11 20:56:13 +08:00
parent 1b047bd975
commit 449cf75da9
3 changed files with 48 additions and 39 deletions

View File

@ -18,7 +18,8 @@ HEADERS += \
../include/circ_elem_array.h \ ../include/circ_elem_array.h \
../include/circ_queue.h \ ../include/circ_queue.h \
../include/ipc.h \ ../include/ipc.h \
../include/def.h ../include/def.h \
../include/rw_lock.h
SOURCES += \ SOURCES += \
../src/shm.cpp \ ../src/shm.cpp \

44
include/rw_lock.h Normal file
View File

@ -0,0 +1,44 @@
#pragma once
#include <atomic>
#include <thread>
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_acquire);
std::size_t unlocked = old + 1;
if (unlocked &&
lc_.compare_exchange_weak(old, unlocked, std::memory_order_acq_rel)) {
break;
}
std::this_thread::yield();
}
}
void r_unlock(void) {
lc_.fetch_sub(1, std::memory_order_release);
}
void w_lock(void) {
std::size_t expected = 0;
while (!lc_.compare_exchange_weak(expected, w_flag, std::memory_order_acq_rel)) {
std::this_thread::yield();
}
}
void w_unlock(void) {
lc_.store(0, std::memory_order_release);
}
};
} // namespace ipc

View File

@ -1,6 +1,4 @@
#include <unordered_map> #include <unordered_map>
#include <atomic>
#include <thread>
#include <memory> #include <memory>
#include <type_traits> #include <type_traits>
#include <cstring> #include <cstring>
@ -10,6 +8,7 @@
#include "ipc.h" #include "ipc.h"
#include "circ_queue.h" #include "circ_queue.h"
#include "rw_lock.h"
namespace { namespace {
@ -27,42 +26,7 @@ using queue_t = circ::queue<msg_t>;
using guard_t = std::unique_ptr<std::remove_pointer_t<handle_t>, void(*)(handle_t)>; using guard_t = std::unique_ptr<std::remove_pointer_t<handle_t>, void(*)(handle_t)>;
std::unordered_map<handle_t, queue_t> h2q__; std::unordered_map<handle_t, queue_t> h2q__;
rw_lock h2q_lc__;
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) {
do {
std::size_t old = lc_.load(std::memory_order_acquire);
std::size_t unlocked = old + 1;
if (unlocked &&
lc_.compare_exchange_weak(old, unlocked, std::memory_order_acq_rel)) {
break;
}
std::this_thread::yield();
} while(1);
}
void r_unlock(void) {
lc_.fetch_sub(1, std::memory_order_release);
}
void w_lock(void) {
std::size_t expected = 0;
while (!lc_.compare_exchange_weak(expected, w_flag, std::memory_order_acq_rel)) {
std::this_thread::yield();
}
}
void w_unlock(void) {
lc_.store(0, std::memory_order_release);
}
} h2q_lc__;
queue_t* queue_of(handle_t h) { queue_t* queue_of(handle_t h) {
if (h == nullptr) { if (h == nullptr) {