From 449cf75da9f3d605d5ac02cd78656ee6db897ed5 Mon Sep 17 00:00:00 2001 From: mutouyun Date: Tue, 11 Dec 2018 20:56:13 +0800 Subject: [PATCH] put rw_lock to a single header file --- build/src.pro | 3 ++- include/rw_lock.h | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/ipc.cpp | 40 ++-------------------------------------- 3 files changed, 48 insertions(+), 39 deletions(-) create mode 100644 include/rw_lock.h diff --git a/build/src.pro b/build/src.pro index 5dbd16f..00292f4 100644 --- a/build/src.pro +++ b/build/src.pro @@ -18,7 +18,8 @@ HEADERS += \ ../include/circ_elem_array.h \ ../include/circ_queue.h \ ../include/ipc.h \ - ../include/def.h + ../include/def.h \ + ../include/rw_lock.h SOURCES += \ ../src/shm.cpp \ diff --git a/include/rw_lock.h b/include/rw_lock.h new file mode 100644 index 0000000..11d0d40 --- /dev/null +++ b/include/rw_lock.h @@ -0,0 +1,44 @@ +#pragma once + +#include +#include + +namespace ipc { + +class rw_lock { + std::atomic_size_t lc_ { 0 }; + + enum : std::size_t { + w_flag = std::numeric_limits::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 diff --git a/src/ipc.cpp b/src/ipc.cpp index 6a19374..00f2bc1 100644 --- a/src/ipc.cpp +++ b/src/ipc.cpp @@ -1,6 +1,4 @@ #include -#include -#include #include #include #include @@ -10,6 +8,7 @@ #include "ipc.h" #include "circ_queue.h" +#include "rw_lock.h" namespace { @@ -27,42 +26,7 @@ using queue_t = circ::queue; using guard_t = std::unique_ptr, void(*)(handle_t)>; std::unordered_map h2q__; - -class rw_lock { - std::atomic_size_t lc_ { 0 }; - - enum : std::size_t { - w_flag = std::numeric_limits::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__; +rw_lock h2q_lc__; queue_t* queue_of(handle_t h) { if (h == nullptr) {