diff options
author | Jon Bratseth <bratseth@yahoo-inc.com> | 2016-06-15 23:09:44 +0200 |
---|---|---|
committer | Jon Bratseth <bratseth@yahoo-inc.com> | 2016-06-15 23:09:44 +0200 |
commit | 72231250ed81e10d66bfe70701e64fa5fe50f712 (patch) | |
tree | 2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /vespalib/src/tests/sync |
Publish
Diffstat (limited to 'vespalib/src/tests/sync')
-rw-r--r-- | vespalib/src/tests/sync/.gitignore | 4 | ||||
-rw-r--r-- | vespalib/src/tests/sync/CMakeLists.txt | 8 | ||||
-rw-r--r-- | vespalib/src/tests/sync/DESC | 1 | ||||
-rw-r--r-- | vespalib/src/tests/sync/FILES | 1 | ||||
-rw-r--r-- | vespalib/src/tests/sync/sync_test.cpp | 323 |
5 files changed, 337 insertions, 0 deletions
diff --git a/vespalib/src/tests/sync/.gitignore b/vespalib/src/tests/sync/.gitignore new file mode 100644 index 00000000000..bee38903897 --- /dev/null +++ b/vespalib/src/tests/sync/.gitignore @@ -0,0 +1,4 @@ +.depend +Makefile +sync_test +vespalib_sync_test_app diff --git a/vespalib/src/tests/sync/CMakeLists.txt b/vespalib/src/tests/sync/CMakeLists.txt new file mode 100644 index 00000000000..944d9d76337 --- /dev/null +++ b/vespalib/src/tests/sync/CMakeLists.txt @@ -0,0 +1,8 @@ +# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +vespa_add_executable(vespalib_sync_test_app + SOURCES + sync_test.cpp + DEPENDS + vespalib +) +vespa_add_test(NAME vespalib_sync_test_app COMMAND vespalib_sync_test_app) diff --git a/vespalib/src/tests/sync/DESC b/vespalib/src/tests/sync/DESC new file mode 100644 index 00000000000..82fc5b4dd36 --- /dev/null +++ b/vespalib/src/tests/sync/DESC @@ -0,0 +1 @@ +sync test. Take a look at sync.cpp for details. diff --git a/vespalib/src/tests/sync/FILES b/vespalib/src/tests/sync/FILES new file mode 100644 index 00000000000..57472ad6c2b --- /dev/null +++ b/vespalib/src/tests/sync/FILES @@ -0,0 +1 @@ +sync.cpp diff --git a/vespalib/src/tests/sync/sync_test.cpp b/vespalib/src/tests/sync/sync_test.cpp new file mode 100644 index 00000000000..5f71c845326 --- /dev/null +++ b/vespalib/src/tests/sync/sync_test.cpp @@ -0,0 +1,323 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +#include <vespa/fastos/fastos.h> +#include <vespa/log/log.h> +LOG_SETUP("sync_test"); +#include <vespa/vespalib/testkit/testapp.h> +#include <vespa/vespalib/util/sync.h> + +using namespace vespalib; + +#define CHECK_LOCKED(m) { TryLock tl(m); EXPECT_TRUE(!tl.hasLock()); } +#define CHECK_UNLOCKED(m) { TryLock tl(m); EXPECT_TRUE(tl.hasLock()); } + +class Test : public TestApp +{ +private: + Lock _lock; + Monitor _monitor; + + LockGuard lockLock() { return LockGuard(_lock); } + LockGuard lockMonitor() { return LockGuard(_monitor); } + MonitorGuard obtainMonitor() { return MonitorGuard(_monitor); } +public: + void testCountDownLatch(); + int Main(); +}; + +void +Test::testCountDownLatch() { + { + CountDownLatch latch(5); + EXPECT_EQUAL(latch.getCount(), 5u); + latch.countDown(); + EXPECT_EQUAL(latch.getCount(), 4u); + latch.countDown(); + EXPECT_EQUAL(latch.getCount(), 3u); + latch.countDown(); + EXPECT_EQUAL(latch.getCount(), 2u); + latch.countDown(); + EXPECT_EQUAL(latch.getCount(), 1u); + latch.countDown(); + EXPECT_EQUAL(latch.getCount(), 0u); + latch.countDown(); + EXPECT_EQUAL(latch.getCount(), 0u); + latch.await(); // should not block + latch.await(); // should not block + } + { + Gate gate; + EXPECT_EQUAL(gate.getCount(), 1u); + gate.countDown(); + EXPECT_EQUAL(gate.getCount(), 0u); + gate.countDown(); + EXPECT_EQUAL(gate.getCount(), 0u); + gate.await(); // should not block + gate.await(); // should not block + } + { + Gate gate; + EXPECT_EQUAL(gate.getCount(), 1u); + EXPECT_EQUAL(gate.await(0), false); + EXPECT_EQUAL(gate.await(10), false); + gate.countDown(); + EXPECT_EQUAL(gate.getCount(), 0u); + EXPECT_EQUAL(gate.await(0), true); + EXPECT_EQUAL(gate.await(10), true); + } +} + +int +Test::Main() +{ + TEST_INIT("sync_test"); + { + Lock lock; + { + CHECK_UNLOCKED(lock); + LockGuard guard(lock); + CHECK_LOCKED(lock); + } + CHECK_UNLOCKED(lock); + { + LockGuard guard(lock); + CHECK_LOCKED(lock); + guard.unlock(); + CHECK_UNLOCKED(lock); + } + } + // you can use a LockGuard to lock a Monitor + { + Monitor monitor; + { + CHECK_UNLOCKED(monitor); + LockGuard guard(monitor); + CHECK_LOCKED(monitor); + } + CHECK_UNLOCKED(monitor); + { + LockGuard guard(monitor); + CHECK_LOCKED(monitor); + guard.unlock(); + CHECK_UNLOCKED(monitor); + } + } + { + Monitor monitor; + { + CHECK_UNLOCKED(monitor); + MonitorGuard guard(monitor); + guard.signal(); + guard.broadcast(); + guard.wait(10); + CHECK_LOCKED(monitor); + } + CHECK_UNLOCKED(monitor); + { + MonitorGuard guard(monitor); + CHECK_LOCKED(monitor); + guard.unlock(); + CHECK_UNLOCKED(monitor); + } + } + // copy/assign is nop, but legal + { + Lock a; + Lock b(a); + b = a; + } + { + Monitor a; + Monitor b(a); + b = a; + } + // you can lock const objects + { + const Lock lock; + CHECK_UNLOCKED(lock); + LockGuard guard(lock); + CHECK_LOCKED(lock); + } + { + const Monitor lock; + CHECK_UNLOCKED(lock); + LockGuard guard(lock); + CHECK_LOCKED(lock); + } + { + const Monitor monitor; + CHECK_UNLOCKED(monitor); + MonitorGuard guard(monitor); + CHECK_LOCKED(monitor); + } + // TryLock hands the lock over to a LockGuard/MonitorGuard + { + Lock lock; + CHECK_UNLOCKED(lock); + TryLock a(lock); + CHECK_LOCKED(lock); + if (a.hasLock()) { + LockGuard guard(a); + CHECK_LOCKED(lock); + } + CHECK_UNLOCKED(lock); + } + { + Monitor mon; + CHECK_UNLOCKED(mon); + TryLock a(mon); + CHECK_LOCKED(mon); + if (a.hasLock()) { + LockGuard guard(a); + CHECK_LOCKED(mon); + } + CHECK_UNLOCKED(mon); + } + { + Monitor mon; + CHECK_UNLOCKED(mon); + TryLock a(mon); + CHECK_LOCKED(mon); + if (a.hasLock()) { + MonitorGuard guard(a); + CHECK_LOCKED(mon); + } + CHECK_UNLOCKED(mon); + } + { + Lock lock; + + CHECK_UNLOCKED(lock); + TryLock a(lock); + CHECK_LOCKED(lock); + TryLock b(lock); + CHECK_LOCKED(lock); + + EXPECT_TRUE(a.hasLock()); + EXPECT_TRUE(!b.hasLock()); + { + CHECK_LOCKED(lock); + EXPECT_TRUE(a.hasLock()); + LockGuard guard(a); + EXPECT_TRUE(!a.hasLock()); + CHECK_LOCKED(lock); + } + CHECK_UNLOCKED(lock); + } + // TryLock will unlock when exiting scope if lock was not passed on + { + Lock lock; + Monitor mon; + CHECK_UNLOCKED(lock); + CHECK_UNLOCKED(mon); + { + TryLock a(lock); + EXPECT_TRUE(a.hasLock()); + TryLock b(mon); + EXPECT_TRUE(b.hasLock()); + CHECK_LOCKED(lock); + CHECK_LOCKED(mon); + } + CHECK_UNLOCKED(lock); + CHECK_UNLOCKED(mon); + } + // TryLock explicitt unlock of lock + { + Lock lock; + TryLock tl(lock); + EXPECT_TRUE(tl.hasLock()); + tl.unlock(); + EXPECT_FALSE(tl.hasLock()); + tl.unlock(); + EXPECT_FALSE(tl.hasLock()); + } + // TryLock explicitt unlock of monitor + { + Monitor lock; + TryLock tl(lock); + EXPECT_TRUE(tl.hasLock()); + tl.unlock(); + EXPECT_FALSE(tl.hasLock()); + tl.unlock(); + EXPECT_FALSE(tl.hasLock()); + } + // LockGuard/MonitorGuard have destructive copy + { + Lock lock; + CHECK_UNLOCKED(lock); + LockGuard a(lock); + CHECK_LOCKED(lock); + { + CHECK_LOCKED(lock); + LockGuard b(a); + CHECK_LOCKED(lock); + } + CHECK_UNLOCKED(lock); + } + { + Monitor mon; + CHECK_UNLOCKED(mon); + MonitorGuard a(mon); + CHECK_LOCKED(mon); + { + CHECK_LOCKED(mon); + MonitorGuard b(a); + CHECK_LOCKED(mon); + } + CHECK_UNLOCKED(mon); + } + // Destructive copy also works for return value handover + { + CHECK_UNLOCKED(_lock); + CHECK_UNLOCKED(_monitor); + { + CHECK_UNLOCKED(_lock); + CHECK_UNLOCKED(_monitor); + LockGuard a(lockLock()); + CHECK_LOCKED(_lock); + CHECK_UNLOCKED(_monitor); + LockGuard b = lockMonitor(); // copy, not assign + CHECK_LOCKED(_lock); + CHECK_LOCKED(_monitor); + } + CHECK_UNLOCKED(_lock); + CHECK_UNLOCKED(_monitor); + } + { + CHECK_UNLOCKED(_monitor); + { + CHECK_UNLOCKED(_monitor); + MonitorGuard guard(obtainMonitor()); + CHECK_LOCKED(_monitor); + } + CHECK_UNLOCKED(_monitor); + } + // Test that guards can be matched to locks/monitors + { + Lock lock1; + Lock lock2; + LockGuard lockGuard1(lock1); + LockGuard lockGuard2(lock2); + EXPECT_TRUE(lockGuard1.locks(lock1)); + EXPECT_FALSE(lockGuard1.locks(lock2)); + EXPECT_TRUE(lockGuard2.locks(lock2)); + EXPECT_FALSE(lockGuard2.locks(lock1)); + lockGuard1.unlock(); + EXPECT_FALSE(lockGuard1.locks(lock1)); + } + { + Monitor lock1; + Monitor lock2; + MonitorGuard lockGuard1(lock1); + MonitorGuard lockGuard2(lock2); + EXPECT_TRUE(lockGuard1.monitors(lock1)); + EXPECT_FALSE(lockGuard1.monitors(lock2)); + EXPECT_TRUE(lockGuard2.monitors(lock2)); + EXPECT_FALSE(lockGuard2.monitors(lock1)); + lockGuard1.unlock(); + EXPECT_FALSE(lockGuard1.monitors(lock1)); + } + testCountDownLatch(); + TEST_DONE(); +} + +TEST_APPHOOK(Test) |