From 35a8f956195f9ad055f8bee7fd4de2c4e0eea6be Mon Sep 17 00:00:00 2001 From: mutouyun Date: Wed, 12 Dec 2018 00:03:42 +0800 Subject: [PATCH] test rw_lock --- include/rw_lock.h | 10 +++++-- test/test_circ.cpp | 2 +- test/test_ipc.cpp | 74 +++++++++++++++++++++++++++++++++++++++++----- test/test_shm.cpp | 2 +- 4 files changed, 76 insertions(+), 12 deletions(-) diff --git a/include/rw_lock.h b/include/rw_lock.h index 11d0d40..6c66f58 100644 --- a/include/rw_lock.h +++ b/include/rw_lock.h @@ -2,6 +2,7 @@ #include #include +#include namespace ipc { @@ -15,7 +16,7 @@ class rw_lock { public: void r_lock(void) { while(1) { - std::size_t old = lc_.load(std::memory_order_acquire); + 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)) { @@ -30,8 +31,11 @@ public: } void w_lock(void) { - std::size_t expected = 0; - while (!lc_.compare_exchange_weak(expected, w_flag, std::memory_order_acq_rel)) { + 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(); } } diff --git a/test/test_circ.cpp b/test/test_circ.cpp index a3603ad..53208db 100644 --- a/test/test_circ.cpp +++ b/test/test_circ.cpp @@ -32,7 +32,7 @@ private slots: void test_prod_cons_performance(); void test_queue(); -} unit__; +} /*unit__*/; #include "test_circ.moc" diff --git a/test/test_ipc.cpp b/test/test_ipc.cpp index 2f199a7..cd36f3b 100644 --- a/test/test_ipc.cpp +++ b/test/test_ipc.cpp @@ -1,4 +1,10 @@ +#include +#include +#include +#include + #include "ipc.h" +#include "rw_lock.h" #include "test.h" namespace { @@ -18,17 +24,71 @@ private slots: #include "test_ipc.moc" void Unit::test_send_recv() { - auto h = ipc::connect("my-ipc"); - QVERIFY(h != nullptr); - char data[] = "hello ipc!"; - QVERIFY(ipc::send(h, data, sizeof(data))); - auto got = ipc::recv(h); - QCOMPARE((char*)got.data(), data); - ipc::disconnect(h); +// auto h = ipc::connect("my-ipc"); +// QVERIFY(h != nullptr); +// char data[] = "hello ipc!"; +// QVERIFY(ipc::send(h, data, sizeof(data))); +// auto got = ipc::recv(h); +// QCOMPARE((char*)got.data(), data); +// ipc::disconnect(h); } void Unit::test_rw_lock() { + std::thread r_trd[4]; + std::thread w_trd[4]; + std::vector datas; + ipc::rw_lock lc; + + for (auto& t : r_trd) { + t = std::thread([&] { + std::vector seq; + std::size_t cnt = 0; + while (1) { + int x = -1; + lc.r_lock(); + if (cnt < datas.size()) { + x = datas[cnt]; + } + lc.r_unlock(); + if (x == 0) break; // quit + if (x != -1) { + seq.push_back(x); + ++cnt; + } + std::this_thread::yield(); + } + std::size_t sum = 0; + for (int i : seq) { + sum += static_cast(i); + } + std::cout << std::endl; + QCOMPARE(sum, 5050 * std::extent::value); + }); + } + + for (auto& t : w_trd) { + t = std::thread([&] { + for (int i = 1; i <= 100; ++i) { + lc.w_lock(); + datas.push_back(i); + lc.w_unlock(); + std::this_thread::yield(); + } + }); + } + + for (auto& t : w_trd) t.join(); + lc.w_lock(); + datas.push_back(0); + lc.w_unlock(); + + for (auto& t : r_trd) t.join(); + + for (int i : datas) { + std::cout << i << " "; + } + std::cout << std::endl; } } // internal-linkage diff --git a/test/test_shm.cpp b/test/test_shm.cpp index 8d096e0..57f7bb0 100644 --- a/test/test_shm.cpp +++ b/test/test_shm.cpp @@ -22,7 +22,7 @@ private slots: void test_get(); void test_hello(); void test_mt(); -} unit__; +} /*unit__*/; #include "test_shm.moc"