From 4ccd636dcb295bc3860c3c9a06c0ecc4b2fb3fa0 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Thu, 31 Dec 2009 16:42:30 +0000 Subject: [PATCH] * Removed return value checks for rw_lock_{read,write}_unlock(). The return values are not really useful, since they should only be != B_OK in case of user error, and will be changed to void. * Added tests for write lock to read lock degrading. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34829 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../system/kernel/unit/lock/RWLockTests.cpp | 94 ++++++++++++++++--- 1 file changed, 83 insertions(+), 11 deletions(-) diff --git a/src/tests/system/kernel/unit/lock/RWLockTests.cpp b/src/tests/system/kernel/unit/lock/RWLockTests.cpp index 3a3930fd06..917328016e 100644 --- a/src/tests/system/kernel/unit/lock/RWLockTests.cpp +++ b/src/tests/system/kernel/unit/lock/RWLockTests.cpp @@ -38,10 +38,10 @@ public: { for (int32 i = 0; i < 3; i++) { TEST_ASSERT(rw_lock_read_lock(&fLock) == B_OK); - TEST_ASSERT(rw_lock_read_unlock(&fLock) == B_OK); + rw_lock_read_unlock(&fLock); TEST_ASSERT(rw_lock_write_lock(&fLock) == B_OK); - TEST_ASSERT(rw_lock_write_unlock(&fLock) == B_OK); + rw_lock_write_unlock(&fLock); } return true; @@ -53,7 +53,7 @@ public: TEST_ASSERT(rw_lock_write_lock(&fLock) == B_OK); for (int32 i = 0; i < 10; i++) - TEST_ASSERT(rw_lock_write_unlock(&fLock) == B_OK); + rw_lock_write_unlock(&fLock); return true; } @@ -66,9 +66,19 @@ public: TEST_ASSERT(rw_lock_read_lock(&fLock) == B_OK); for (int32 i = 0; i < 10; i++) - TEST_ASSERT(rw_lock_read_unlock(&fLock) == B_OK); + rw_lock_read_unlock(&fLock); - TEST_ASSERT(rw_lock_write_unlock(&fLock) == B_OK); + rw_lock_write_unlock(&fLock); + + return true; + } + + bool TestDegrade(TestContext& context) + { + TEST_ASSERT(rw_lock_write_lock(&fLock) == B_OK); + TEST_ASSERT(rw_lock_read_lock(&fLock) == B_OK); + rw_lock_write_unlock(&fLock); + rw_lock_read_unlock(&fLock); return true; } @@ -85,6 +95,12 @@ public: &RWLockTest::TestConcurrentWriteNestedReadThread); } + bool TestConcurrentDegrade(TestContext& context) + { + return _RunConcurrentTest(context, + &RWLockTest::TestConcurrentDegradeThread); + } + // thread function wrappers @@ -100,6 +116,12 @@ public: fTestOK = false; } + void TestConcurrentDegradeThread(TestContext& context, void* _index) + { + if (!_TestConcurrentDegradeThread(context, (addr_t)_index)) + fTestOK = false; + } + private: bool _RunConcurrentTest(TestContext& context, void (RWLockTest::*method)(TestContext&, void*)) @@ -153,11 +175,11 @@ private: for (int k = 0; fTestOK && k < 255; k++) { TEST_ASSERT(rw_lock_read_lock(&fLock) == B_OK); uint64 count = fLockCount; - TEST_ASSERT(rw_lock_read_unlock(&fLock) == B_OK); + rw_lock_read_unlock(&fLock); TEST_ASSERT(rw_lock_write_lock(&fLock) == B_OK); fLockCount += (uint64)1 << bitShift; - TEST_ASSERT(rw_lock_write_unlock(&fLock) == B_OK); + rw_lock_write_unlock(&fLock); int value = (count >> bitShift) & 0xff; TEST_ASSERT_PRINT(value == k, @@ -168,7 +190,7 @@ private: TEST_ASSERT(rw_lock_write_lock(&fLock) == B_OK); fLockCount -= (uint64)255 << bitShift; - TEST_ASSERT(rw_lock_write_unlock(&fLock) == B_OK); + rw_lock_write_unlock(&fLock); iteration++; } while (fTestOK && system_time() - startTime < kConcurrentTestTime); @@ -195,11 +217,11 @@ private: TEST_ASSERT(rw_lock_read_lock(&fLock) == B_OK); uint64 count = fLockCount; - TEST_ASSERT(rw_lock_read_unlock(&fLock) == B_OK); + rw_lock_read_unlock(&fLock); fLockCount += (uint64)1 << bitShift; - TEST_ASSERT(rw_lock_write_unlock(&fLock) == B_OK); + rw_lock_write_unlock(&fLock); int value = (count >> bitShift) & 0xff; TEST_ASSERT_PRINT(value == k, @@ -210,7 +232,55 @@ private: TEST_ASSERT(rw_lock_write_lock(&fLock) == B_OK); fLockCount -= (uint64)255 << bitShift; - TEST_ASSERT(rw_lock_write_unlock(&fLock) == B_OK); + rw_lock_write_unlock(&fLock); + + iteration++; + } while (fTestOK && system_time() - startTime < kConcurrentTestTime); + + return true; + } + + bool _TestConcurrentDegradeThread(TestContext& context, int32 threadIndex) + { + if (!fTestOK) + return false; + + int bitShift = 8 * threadIndex; + + while (!fTestGo) { + } + + bigtime_t startTime = system_time(); + uint64 iteration = 0; + do { + for (int k = 0; fTestOK && k < 255; k++) { + TEST_ASSERT(rw_lock_read_lock(&fLock) == B_OK); + uint64 count = fLockCount; + rw_lock_read_unlock(&fLock); + + TEST_ASSERT(rw_lock_write_lock(&fLock) == B_OK); + fLockCount += (uint64)1 << bitShift; + uint64 newCount = fLockCount; + + // degrade + TEST_ASSERT(rw_lock_read_lock(&fLock) == B_OK); + rw_lock_write_unlock(&fLock); + + uint64 unchangedCount = fLockCount; + + rw_lock_read_unlock(&fLock); + + int value = (count >> bitShift) & 0xff; + TEST_ASSERT_PRINT(value == k, + "thread index: %" B_PRId32 ", iteration: %" B_PRId32 + ", value: %d vs %d, count: %#" B_PRIx64, threadIndex, + iteration, value, k, count); + TEST_ASSERT(newCount == unchangedCount); + } + + TEST_ASSERT(rw_lock_write_lock(&fLock) == B_OK); + fLockCount -= (uint64)255 << bitShift; + rw_lock_write_unlock(&fLock); iteration++; } while (fTestOK && system_time() - startTime < kConcurrentTestTime); @@ -234,8 +304,10 @@ create_rw_lock_test_suite() ADD_STANDARD_TEST(suite, RWLockTest, TestSimple); ADD_STANDARD_TEST(suite, RWLockTest, TestNestedWrite); ADD_STANDARD_TEST(suite, RWLockTest, TestNestedWriteRead); + ADD_STANDARD_TEST(suite, RWLockTest, TestDegrade); ADD_STANDARD_TEST(suite, RWLockTest, TestConcurrentWriteRead); ADD_STANDARD_TEST(suite, RWLockTest, TestConcurrentWriteNestedRead); + ADD_STANDARD_TEST(suite, RWLockTest, TestConcurrentDegrade); return suite; }