From 72bffb0807925a156b076b71f78c848a08d27b87 Mon Sep 17 00:00:00 2001
From: lichao <lichao@aiotlink.com>
Date: 星期四, 29 四月 2021 10:55:35 +0800
Subject: [PATCH] refactor mutex.

---
 utest/robust_test.cpp |  104 +++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 91 insertions(+), 13 deletions(-)

diff --git a/utest/robust_test.cpp b/utest/robust_test.cpp
index 0d54b46..9384c10 100644
--- a/utest/robust_test.cpp
+++ b/utest/robust_test.cpp
@@ -3,8 +3,13 @@
 
 using namespace robust;
 
+enum {
+	eLockerBits = 32,
+	eLockerMask = MaskBits(sizeof(int) * 8),
+};
+
 typedef CircularBuffer<int64_t, Allocator<int64_t>> Rcb;
-Rcb *GetRCBImpl(SharedMemory &shm, const int nelem)
+Rcb *GetRCB(SharedMemory &shm, const int nelem)
 {
 	int cap = nelem + 1;
 	typedef uint64_t Data;
@@ -15,24 +20,13 @@
 	}
 	return nullptr;
 }
-Rcb *GetRCB(SharedMemory &shm, const int nelem)
-{
-	void **pStore = shm.FindOrCreate<void *>("test_rcb_pointer", nullptr);
-	if (pStore) {
-		if (!*pStore) {
-			*pStore = GetRCBImpl(shm, nelem);
-		}
-		return (Rcb *) *pStore;
-	}
-	return nullptr;
-}
 
 void MySleep()
 {
 	std::this_thread::sleep_for(2us);
 }
 
-BOOST_AUTO_TEST_CASE(RobustTest)
+BOOST_AUTO_TEST_CASE(QueueTest)
 {
 	SharedMemory &shm = TestShm();
 	shm.Remove();
@@ -112,4 +106,88 @@
 	threads.WaitAll();
 	printf("total: %ld, expected: %ld\n", total.load(), correct_total);
 	BOOST_CHECK_EQUAL(total.load(), correct_total);
+}
+
+BOOST_AUTO_TEST_CASE(MutexTest)
+{
+	typedef robust::Mutex RobustMutex;
+
+	for (int i = 0; i < 20; ++i) {
+		int size = i;
+		int left = size & 7;
+		int rsize = size + ((8 - left) & 7);
+		printf("size: %3d, rsize: %3d\n", size, rsize);
+	}
+	SharedMemory &shm = TestShm();
+	// shm.Remove();
+	// return;
+	GlobalInit(shm);
+
+	const std::string mtx_name("test_mutex");
+	const std::string int_name("test_int");
+	auto mtx = shm.FindOrCreate<RobustMutex>(mtx_name);
+	auto pi = shm.FindOrCreate<int>(int_name, 100);
+
+	std::mutex m;
+	typedef std::chrono::steady_clock Clock;
+	auto Now = []() { return Clock::now().time_since_epoch(); };
+	if (pi) {
+		auto old = *pi;
+		printf("int : %d, add1: %d\n", old, ++*pi);
+	}
+
+	{
+		boost::timer::auto_cpu_timer timer;
+		const int ntimes = 1000 * 1000;
+		printf("test lock/unlock %d times: ", ntimes);
+		RobustMutex mutex;
+		auto Lock = [&]() {
+			for (int i = 0; i < ntimes; ++i) {
+				mutex.lock();
+				mutex.unlock();
+			}
+		};
+		std::thread t1(Lock), t2(Lock);
+		t1.join();
+		t2.join();
+	}
+
+	auto MSFromNow = [](const int ms) {
+		using namespace boost::posix_time;
+		ptime cur = boost::posix_time::microsec_clock::universal_time();
+		return cur + millisec(ms);
+	};
+
+	auto TryLock = [&]() {
+		if (mtx->try_lock()) {
+			printf("try_lock ok\n");
+			return true;
+		} else {
+			printf("try_lock failed\n");
+			return false;
+		}
+	};
+	auto Unlock = [&]() {
+		mtx->unlock();
+		printf("unlocked\n");
+	};
+
+	if (mtx) {
+		printf("mtx exists\n");
+		if (TryLock()) {
+			auto op = [&]() {
+				if (TryLock()) {
+					Unlock();
+				}
+			};
+			op();
+			std::thread t(op);
+			t.join();
+			// Unlock();
+		} else {
+			// mtx->unlock();
+		}
+	} else {
+		printf("mtx not exists\n");
+	}
 }
\ No newline at end of file

--
Gitblit v1.8.0