From ea52920b7d61a8356a6d0410b5a5874781364681 Mon Sep 17 00:00:00 2001 From: mutouyun Date: Sat, 5 Jan 2019 14:35:25 +0800 Subject: [PATCH] msleep(1) --- include/circ_queue.h | 9 +++++++-- include/rw_lock.h | 16 +++++++++++----- test/test_ipc.cpp | 8 ++++---- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/include/circ_queue.h b/include/circ_queue.h index 10e09a7..345e612 100644 --- a/include/circ_queue.h +++ b/include/circ_queue.h @@ -7,6 +7,7 @@ #include #include #include +#include #include "def.h" #include "circ_elem_array.h" @@ -95,7 +96,7 @@ public: template static queue* multi_wait_for(F&& upd) noexcept { - while (1) { + for (uint_t<32> k = 0;;) { auto [ques, size] = upd(); for (std::size_t i = 0; i < static_cast(size); ++i) { queue* que = ques[i]; @@ -105,7 +106,11 @@ public: return que; } } - std::this_thread::yield(); + if (k < 4096) { + std::this_thread::yield(); + ++k; + } + else std::this_thread::sleep_for(std::chrono::milliseconds(1)); } } diff --git a/include/rw_lock.h b/include/rw_lock.h index 49f1f6d..895e11a 100644 --- a/include/rw_lock.h +++ b/include/rw_lock.h @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -56,12 +57,17 @@ namespace ipc { -inline void yield(unsigned k) noexcept { +inline void yield(unsigned& k) noexcept { if (k < 4) { /* Do nothing */ } else if (k < 16) { IPC_LOCK_PAUSE_(); } else - { std::this_thread::yield(); } + if (k < 32) { std::this_thread::yield(); } + else { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + return; + } + ++k; } } // namespace ipc @@ -88,14 +94,14 @@ public: rw_lock& operator=(rw_lock&&) = delete; void lock() noexcept { - for (unsigned k = 0;; ++k) { + for (unsigned k = 0;;) { auto old = lc_.fetch_or(w_flag, std::memory_order_acquire); if (!old) return; // got w-lock if (!(old & w_flag)) break; // other thread having r-lock yield(k); // other thread having w-lock } // wait for reading finished - for (unsigned k = 0; lc_.load(std::memory_order_acquire) & w_mask; ++k) { + for (unsigned k = 0; lc_.load(std::memory_order_acquire) & w_mask;) { yield(k); } } @@ -106,7 +112,7 @@ public: void lock_shared() noexcept { auto old = lc_.load(std::memory_order_relaxed); - for (unsigned k = 0;; ++k) { + for (unsigned k = 0;;) { // if w_flag set, just continue if (old & w_flag) { yield(k); diff --git a/test/test_ipc.cpp b/test/test_ipc.cpp index bcb7157..3bb481c 100644 --- a/test/test_ipc.cpp +++ b/test/test_ipc.cpp @@ -314,10 +314,10 @@ void test_lock_performance() { } void Unit::test_rw_lock() { -// test_lock_performance<1, 1>(); -// test_lock_performance<4, 4>(); -// test_lock_performance<1, 8>(); -// test_lock_performance<8, 1>(); + test_lock_performance<1, 1>(); + test_lock_performance<4, 4>(); + test_lock_performance<1, 8>(); + test_lock_performance<8, 1>(); } void Unit::test_send_recv() {