test rw_lock

This commit is contained in:
mutouyun 2018-12-12 00:03:42 +08:00
parent 9c9ca8f5c4
commit 35a8f95619
4 changed files with 76 additions and 12 deletions

View File

@ -2,6 +2,7 @@
#include <atomic> #include <atomic>
#include <thread> #include <thread>
#include <limits>
namespace ipc { namespace ipc {
@ -15,7 +16,7 @@ class rw_lock {
public: public:
void r_lock(void) { void r_lock(void) {
while(1) { 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; std::size_t unlocked = old + 1;
if (unlocked && if (unlocked &&
lc_.compare_exchange_weak(old, unlocked, std::memory_order_acq_rel)) { lc_.compare_exchange_weak(old, unlocked, std::memory_order_acq_rel)) {
@ -30,8 +31,11 @@ public:
} }
void w_lock(void) { void w_lock(void) {
std::size_t expected = 0; while (1) {
while (!lc_.compare_exchange_weak(expected, w_flag, std::memory_order_acq_rel)) { std::size_t expected = 0;
if (lc_.compare_exchange_weak(expected, w_flag, std::memory_order_acq_rel)) {
break;
}
std::this_thread::yield(); std::this_thread::yield();
} }
} }

View File

@ -32,7 +32,7 @@ private slots:
void test_prod_cons_performance(); void test_prod_cons_performance();
void test_queue(); void test_queue();
} unit__; } /*unit__*/;
#include "test_circ.moc" #include "test_circ.moc"

View File

@ -1,4 +1,10 @@
#include <thread>
#include <vector>
#include <type_traits>
#include <iostream>
#include "ipc.h" #include "ipc.h"
#include "rw_lock.h"
#include "test.h" #include "test.h"
namespace { namespace {
@ -18,17 +24,71 @@ private slots:
#include "test_ipc.moc" #include "test_ipc.moc"
void Unit::test_send_recv() { void Unit::test_send_recv() {
auto h = ipc::connect("my-ipc"); // auto h = ipc::connect("my-ipc");
QVERIFY(h != nullptr); // QVERIFY(h != nullptr);
char data[] = "hello ipc!"; // char data[] = "hello ipc!";
QVERIFY(ipc::send(h, data, sizeof(data))); // QVERIFY(ipc::send(h, data, sizeof(data)));
auto got = ipc::recv(h); // auto got = ipc::recv(h);
QCOMPARE((char*)got.data(), data); // QCOMPARE((char*)got.data(), data);
ipc::disconnect(h); // ipc::disconnect(h);
} }
void Unit::test_rw_lock() { void Unit::test_rw_lock() {
std::thread r_trd[4];
std::thread w_trd[4];
std::vector<int> datas;
ipc::rw_lock lc;
for (auto& t : r_trd) {
t = std::thread([&] {
std::vector<int> 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<std::size_t>(i);
}
std::cout << std::endl;
QCOMPARE(sum, 5050 * std::extent<decltype(w_trd)>::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 } // internal-linkage

View File

@ -22,7 +22,7 @@ private slots:
void test_get(); void test_get();
void test_hello(); void test_hello();
void test_mt(); void test_mt();
} unit__; } /*unit__*/;
#include "test_shm.moc" #include "test_shm.moc"