aboutsummaryrefslogtreecommitdiffstats
path: root/vespalib/src
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2020-10-14 19:42:38 +0000
committerHenning Baldersheim <balder@yahoo-inc.com>2020-10-15 10:13:12 +0000
commitb6a9d5894dc0d5ae8f896c4346a45fb20cf600b6 (patch)
treead58d5aa3a4c7505124b91b7629875d98875a6bd /vespalib/src
parent36eb309ed6b9df96c4138fc57d3b002dd6dc6412 (diff)
GC unused vespalib::MOnitor.
Diffstat (limited to 'vespalib/src')
-rw-r--r--vespalib/src/tests/sync/sync_test.cpp258
-rw-r--r--vespalib/src/vespa/vespalib/util/CMakeLists.txt1
-rw-r--r--vespalib/src/vespa/vespalib/util/overview.h11
-rw-r--r--vespalib/src/vespa/vespalib/util/sync.cpp99
-rw-r--r--vespalib/src/vespa/vespalib/util/sync.h209
5 files changed, 38 insertions, 540 deletions
diff --git a/vespalib/src/tests/sync/sync_test.cpp b/vespalib/src/tests/sync/sync_test.cpp
index 3a2cf0ea7a0..417a9779f9d 100644
--- a/vespalib/src/tests/sync/sync_test.cpp
+++ b/vespalib/src/tests/sync/sync_test.cpp
@@ -1,230 +1,48 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include <vespa/vespalib/testkit/testapp.h>
-#include <vespa/vespalib/util/sync.h>
+#include <vespa/vespalib/util/gate.h>
-namespace vespalib {
-class TryLock
-{
-private:
- friend class LockGuard;
- friend class MonitorGuard;
-
- std::unique_lock<std::mutex> _guard;
- std::condition_variable *_cond;
-
-public:
- TryLock(const Monitor &mon)
- : _guard(*mon._mutex, std::try_to_lock),
- _cond(_guard ? mon._cond.get() : nullptr)
- {}
- ~TryLock() = default;
-
- TryLock(const TryLock &) = delete;
- TryLock &operator=(const TryLock &) = delete;
-
- /**
- * @brief Check whether this object holds a lock
- *
- * @return true if this object holds a lock
- **/
- bool hasLock() const { return static_cast<bool>(_guard); }
- void unlock() {
- if (_guard) {
- _guard.unlock();
- _cond = nullptr;
- }
- }
-};
-
-}
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:
- Monitor _monitor;
-
- LockGuard lockMonitor() { return LockGuard(_monitor); }
- MonitorGuard obtainMonitor() { return MonitorGuard(_monitor); }
-public:
- ~Test() override;
- void testCountDownLatch();
- int Main() override;
-};
-
-Test::~Test() = default;
-
-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);
- }
+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
+}
+TEST("test gate dropping below zero") {
+ 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
}
-int
-Test::Main()
-{
- TEST_INIT("sync_test");
- // 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);
- }
- }
-
- // you can lock const objects
-
- {
- const Monitor lock;
- CHECK_UNLOCKED(lock);
- LockGuard guard(lock);
- CHECK_LOCKED(lock);
- }
- {
- const Monitor monitor;
- CHECK_UNLOCKED(monitor);
- MonitorGuard guard(monitor);
- CHECK_LOCKED(monitor);
- }
- // LockGuard/MonitorGuard have destructive move
- {
- Monitor lock;
- CHECK_UNLOCKED(lock);
- LockGuard a(lock);
- CHECK_LOCKED(lock);
- {
- CHECK_LOCKED(lock);
- LockGuard b(std::move(a));
- CHECK_LOCKED(lock);
- }
- CHECK_UNLOCKED(lock);
- }
- {
- Monitor mon;
- CHECK_UNLOCKED(mon);
- MonitorGuard a(mon);
- CHECK_LOCKED(mon);
- {
- CHECK_LOCKED(mon);
- MonitorGuard b(std::move(a));
- CHECK_LOCKED(mon);
- }
- CHECK_UNLOCKED(mon);
- }
- // Destructive copy also works for return value handover
- {
- CHECK_UNLOCKED(_monitor);
- {
- CHECK_UNLOCKED(_monitor);
- CHECK_UNLOCKED(_monitor);
- LockGuard b = lockMonitor(); // copy, not assign
- CHECK_LOCKED(_monitor);
- }
- 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
- {
- Monitor lock1;
- Monitor 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("test gate non blocking await return correct states") {
+ 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);
}
-TEST_APPHOOK(Test)
+TEST_MAIN() { TEST_RUN_ALL(); }
diff --git a/vespalib/src/vespa/vespalib/util/CMakeLists.txt b/vespalib/src/vespa/vespalib/util/CMakeLists.txt
index ea2189fc3a8..610310fd43c 100644
--- a/vespalib/src/vespa/vespalib/util/CMakeLists.txt
+++ b/vespalib/src/vespa/vespalib/util/CMakeLists.txt
@@ -49,7 +49,6 @@ vespa_add_library(vespalib_vespalib_util OBJECT
stash.cpp
string_hash.cpp
stringfmt.cpp
- sync.cpp
thread.cpp
thread_bundle.cpp
threadstackexecutor.cpp
diff --git a/vespalib/src/vespa/vespalib/util/overview.h b/vespalib/src/vespa/vespalib/util/overview.h
index 7849887a14c..311071b4429 100644
--- a/vespalib/src/vespa/vespalib/util/overview.h
+++ b/vespalib/src/vespa/vespalib/util/overview.h
@@ -22,17 +22,6 @@
*
* vespalib::GenCnt
*
- * Synchronization classes
- *
- * vespalib::Lock
- * <BR> vespalib::LockGuard
- * <BR> vespalib::Monitor
- * <BR> vespalib::TryLock
- * <BR> vespalib::MonitorGuard
- * <BR> vespalib::RWLock
- * <BR> vespalib::RWLockReader
- * <BR> vespalib::RWLockWriter
- *
* Reference counting
*
* <BR> vespalib::ReferenceCounter
diff --git a/vespalib/src/vespa/vespalib/util/sync.cpp b/vespalib/src/vespa/vespalib/util/sync.cpp
deleted file mode 100644
index 1f7a5215c46..00000000000
--- a/vespalib/src/vespa/vespalib/util/sync.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-
-#include "sync.h"
-#include <cassert>
-
-namespace vespalib {
-
-Monitor::Monitor() noexcept
- : _mutex(std::make_unique<std::mutex>()),
- _cond(std::make_unique<std::condition_variable>())
-{}
-Monitor::Monitor(Monitor &&rhs) noexcept = default;
-Monitor::~Monitor() = default;
-
-LockGuard::LockGuard() : _guard() {}
-
-LockGuard::LockGuard(LockGuard &&rhs) noexcept : _guard(std::move(rhs._guard)) { }
-LockGuard::LockGuard(const Monitor &lock) : _guard(*lock._mutex) { }
-
-LockGuard &
-LockGuard::operator=(LockGuard &&rhs) noexcept{
- if (this != &rhs) {
- _guard = std::move(rhs._guard);
- }
- return *this;
-}
-
-void
-LockGuard::unlock() {
- if (_guard) {
- _guard.unlock();
- }
-}
-LockGuard::~LockGuard() = default;
-
-bool
-LockGuard::locks(const Monitor & lock) const {
- return (_guard && _guard.mutex() == lock._mutex.get());
-}
-
-MonitorGuard::MonitorGuard() : _guard(), _cond(nullptr) {}
-MonitorGuard::MonitorGuard(MonitorGuard &&rhs) noexcept
- : _guard(std::move(rhs._guard)),
- _cond(rhs._cond)
-{
- rhs._cond = nullptr;
-}
-MonitorGuard::MonitorGuard(const Monitor &monitor)
- : _guard(*monitor._mutex),
- _cond(monitor._cond.get())
-{ }
-
-MonitorGuard &
-MonitorGuard::operator=(MonitorGuard &&rhs) noexcept {
- if (this != &rhs) {
- _guard = std::move(rhs._guard);
- _cond = rhs._cond;
- rhs._cond = nullptr;
- }
- return *this;
-}
-
-void
-MonitorGuard::unlock() {
- assert(_guard);
- _guard.unlock();
- _cond = nullptr;
-}
-void
-MonitorGuard::wait() {
- _cond->wait(_guard);
-}
-bool
-MonitorGuard::wait(int msTimeout) {
- return wait(std::chrono::milliseconds(msTimeout));
-}
-bool
-MonitorGuard::wait(std::chrono::nanoseconds timeout) {
- return _cond->wait_for(_guard, timeout) == std::cv_status::no_timeout;
-}
-void
-MonitorGuard::signal() {
- _cond->notify_one();
-}
-void
-MonitorGuard::broadcast() {
- _cond->notify_all();
-}
-void
-MonitorGuard::unsafeSignalUnlock() {
- _guard.unlock();
- _cond->notify_one();
- _cond = nullptr;
-}
-
-MonitorGuard::~MonitorGuard() = default;
-
-} // namespace vespalib
-
diff --git a/vespalib/src/vespa/vespalib/util/sync.h b/vespalib/src/vespa/vespalib/util/sync.h
deleted file mode 100644
index d66a53cf539..00000000000
--- a/vespalib/src/vespa/vespalib/util/sync.h
+++ /dev/null
@@ -1,209 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-
-#pragma once
-
-#include "time.h"
-#include <mutex>
-#include <condition_variable>
-
-namespace vespalib {
-
-/**
- * @brief A Monitor is a synchronization primitive used to protect
- * data access and also facilitate signaling and waiting between
- * threads.
- *
- * A LockGuard can be used to obtain a lock on a Monitor. If you also
- * want to send or wait for signals, you need to use a MonitorGuard.
- *
- * It is possible to obtain a lock on a const Monitor object.
- *
- * @see TryLock
- **/
-class Monitor
-{
-private:
- friend class LockGuard;
- friend class MonitorGuard;
- friend class TryLock;
-
- std::unique_ptr<std::mutex> _mutex;
- std::unique_ptr<std::condition_variable> _cond;
-public:
- /**
- * @brief Create a new Monitor.
- *
- * Creates a Monitor that has mutex instrumentation disabled.
- **/
- Monitor() noexcept;
- Monitor(Monitor && rhs) noexcept;
- ~Monitor();
-};
-
-
-/**
- * @brief A LockGuard holds the lock on either a Lock or a Monitor.
- *
- * LockGuards are typically created on the stack to hold a lock within
- * a scope. If needed, the unlock method may be used to release the
- * lock before exiting scope.
- *
- * LockGuard has destructive copy. Copying a LockGuard has the
- * semantic of transferring the lock from one object to the
- * other. Note that assignment is not legal, and that copying a
- * LockGuard that does not have a lock will result in an assert.
- **/
-class LockGuard
-{
-private:
- std::unique_lock<std::mutex> _guard;
-public:
- /**
- * @brief A noop guard without any mutex.
- **/
- LockGuard();
- LockGuard(const LockGuard &rhs) = delete;
- LockGuard &operator=(const LockGuard &) = delete;
-
- /**
- * @brief Steal the lock from the given LockGuard
- *
- * @param rhs steal the lock from this one
- **/
- LockGuard(LockGuard &&rhs) noexcept;
- /**
- * @brief Obtain the lock represented by the given Lock object.
- *
- * The method will block until the lock can be obtained.
- *
- * @param lock take it
- **/
- LockGuard(const Monitor &lock);
-
- LockGuard &operator=(LockGuard &&rhs) noexcept;
-
- /**
- * @brief Release the lock held by this object.
- *
- * No methods may be invoked after invoking unlock (except the
- * destructor). Note that this method should only be used if you
- * need to release the lock before the object is destructed, as
- * the destructor will release the lock.
- **/
- void unlock();
- /**
- * @brief Release the lock held by this object if unlock has not
- * been called.
- **/
- ~LockGuard();
-
- /**
- * Allow code to match guard with lock. This allows functions to take a
- * guard ref as input, ensuring that the caller have grabbed a lock.
- */
- bool locks(const Monitor& lock) const;
-};
-
-
-/**
- * @brief A MonitorGuard holds the lock on a Monitor and supports
- * sending and waiting for signals.
- *
- * MonitorGuards are typically created on the stack to hold a lock
- * within a scope. If needed, the unlock method may be used to release
- * the lock before exiting scope.
- *
- * MonitorGuard has destructive copy. Copying a MonitorGuard has the
- * semantic of transferring the lock from one object to the
- * other. Note that assignment is not legal, and that copying a
- * MonitorGuard that does not have a lock will result in an assert.
- **/
-class MonitorGuard
-{
-private:
- std::unique_lock<std::mutex> _guard;
- std::condition_variable *_cond;
- MonitorGuard &operator=(const MonitorGuard &) = delete;
-
-public:
- /**
- * @brief A noop guard without any condition.
- **/
- MonitorGuard();
- MonitorGuard(const MonitorGuard &rhs) = delete;
- /**
- * @brief Steal the lock from the given MonitorGuard
- *
- * @param rhs steal the lock from this one
- **/
- MonitorGuard(MonitorGuard &&rhs) noexcept;
- /**
- * @brief Obtain the lock on the given Monitor object.
- *
- * The method will block until the lock can be obtained.
- *
- * @param monitor take the lock on it
- **/
- MonitorGuard(const Monitor &monitor);
-
- MonitorGuard &operator=(MonitorGuard &&rhs) noexcept;
-
-
- /**
- * @brief Release the lock held by this object.
- *
- * No methods may be invoked after invoking this one (except the
- * destructor). Note that this method should only be used if you
- * need to release the lock before this object is destructed, as
- * the destructor will release the lock.
- **/
- void unlock();
- /**
- * @brief Wait for a signal on the underlying Monitor.
- **/
- void wait();
- /**
- * @brief Wait for a signal on the underlying Monitor with the
- * given timeout.
- *
- * @param msTimeout timeout in milliseconds
- * @return true if a signal was received, false if the wait timed out.
- **/
- bool wait(int msTimeout);
- bool wait(duration timeout);
- /**
- * @brief Send a signal to a single waiter on the underlying
- * Monitor.
- **/
- void signal();
- /**
- * @brief Send a signal to all waiters on the underlying Monitor.
- **/
- void broadcast();
- /**
- * @brief Send a signal to a single waiter on the underlying
- * Monitor, but unlock the monitor right before doing so.
- *
- * This is inherently unsafe and the caller needs external
- * synchronization to ensure that the underlying Monitor object
- * will live long enough to be signaled.
- **/
- void unsafeSignalUnlock();
-
- /**
- * @brief Release the lock held by this object if unlock has not
- * been called.
- **/
- ~MonitorGuard();
-
- /**
- * Allow code to match guard with lock. This allows functions to take a
- * guard ref as input, ensuring that the caller have grabbed a lock.
- */
- bool monitors(const Monitor& m) const {
- return (_cond != nullptr && _cond == m._cond.get());
- }
-};
-
-} // namespace vespalib
-