aboutsummaryrefslogtreecommitdiffstats
path: root/vespalib
diff options
context:
space:
mode:
authorTor Egge <Tor.Egge@oath.com>2017-12-11 22:15:33 +0000
committerTor Egge <Tor.Egge@oath.com>2017-12-11 22:16:51 +0000
commitad70d622d76fd6a59272b16da1a3787d5f85c193 (patch)
tree6efa051b6eda9efb394baa71437062dba9e7f21d /vespalib
parent6fb88055e04ba273f5edb1d87f0423f45dc1e470 (diff)
Factor out CountDownLatch and Gate to separate header files.
Diffstat (limited to 'vespalib')
-rw-r--r--vespalib/src/vespa/vespalib/testkit/test_hook.h2
-rw-r--r--vespalib/src/vespa/vespalib/testkit/time_bomb.h2
-rw-r--r--vespalib/src/vespa/vespalib/util/count_down_latch.h95
-rw-r--r--vespalib/src/vespa/vespalib/util/gate.h22
-rw-r--r--vespalib/src/vespa/vespalib/util/simple_thread_bundle.h1
-rw-r--r--vespalib/src/vespa/vespalib/util/sync.h103
-rw-r--r--vespalib/src/vespa/vespalib/util/thread.h1
-rw-r--r--vespalib/src/vespa/vespalib/util/threadstackexecutorbase.h1
8 files changed, 122 insertions, 105 deletions
diff --git a/vespalib/src/vespa/vespalib/testkit/test_hook.h b/vespalib/src/vespa/vespalib/testkit/test_hook.h
index 336e965b0b1..28419c0b31b 100644
--- a/vespalib/src/vespa/vespalib/testkit/test_hook.h
+++ b/vespalib/src/vespa/vespalib/testkit/test_hook.h
@@ -2,7 +2,7 @@
#pragma once
-#include <vespa/vespalib/util/sync.h>
+#include <vespa/vespalib/util/count_down_latch.h>
#include <vespa/vespalib/util/barrier.h>
#include <string>
#include <vector>
diff --git a/vespalib/src/vespa/vespalib/testkit/time_bomb.h b/vespalib/src/vespa/vespalib/testkit/time_bomb.h
index 5b39e27db79..8412e4b8661 100644
--- a/vespalib/src/vespa/vespalib/testkit/time_bomb.h
+++ b/vespalib/src/vespa/vespalib/testkit/time_bomb.h
@@ -2,7 +2,7 @@
#pragma once
-#include <vespa/vespalib/util/sync.h>
+#include <vespa/vespalib/util/gate.h>
#include <thread>
namespace vespalib {
diff --git a/vespalib/src/vespa/vespalib/util/count_down_latch.h b/vespalib/src/vespa/vespalib/util/count_down_latch.h
new file mode 100644
index 00000000000..66ef1e44cee
--- /dev/null
+++ b/vespalib/src/vespa/vespalib/util/count_down_latch.h
@@ -0,0 +1,95 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#pragma once
+
+#include <mutex>
+#include <condition_variable>
+#include <chrono>
+
+namespace vespalib {
+
+/**
+ * A countdown latch helps one or more threads wait for the completion
+ * of a number of operations performed by other threads. Specifically,
+ * any thread invoking the await method will block until the countDown
+ * method has been invoked an appropriate number of times. The
+ * countdown latch is created with a count. Each invocation of
+ * countDown will reduce the current count. When the count reaches 0,
+ * the threads blocked in await will be unblocked. When the count is
+ * 0, additional invocations of await will not block and additional
+ * invocations of countDown will have no effect.
+ **/
+class CountDownLatch
+{
+private:
+ std::mutex _lock;
+ std::condition_variable _cond;
+ uint32_t _count;
+
+ CountDownLatch(const CountDownLatch &rhs) = delete;
+ CountDownLatch(CountDownLatch &&rhs) = delete;
+ CountDownLatch &operator=(const CountDownLatch &rhs) = delete;
+ CountDownLatch &operator=(CountDownLatch &&rhs) = delete;
+
+public:
+ /**
+ * Create a countdown latch with the given initial count.
+ *
+ * @param cnt initial count
+ **/
+ CountDownLatch(uint32_t cnt) : _lock(), _cond(), _count(cnt) {}
+
+ /**
+ * Count down this latch. When the count reaches 0, all threads
+ * blocked in the await method will be unblocked.
+ **/
+ void countDown() {
+ std::lock_guard<std::mutex> guard(_lock);
+ if (_count != 0) {
+ --_count;
+ if (_count == 0) {
+ _cond.notify_all();
+ }
+ }
+ }
+
+ /**
+ * Wait for this latch to count down to 0. This method will block
+ * until the countDown method has been invoked enough times to
+ * reduce the count to 0.
+ **/
+ void await() {
+ std::unique_lock<std::mutex> guard(_lock);
+ _cond.wait(guard, [this]() { return (_count == 0); });
+ }
+
+ /**
+ * Wait for this latch to count down to 0. This method will block
+ * until the countDown method has been invoked enough times to
+ * reduce the count to 0 or the given amount of time has elapsed.
+ *
+ * @param maxwait the maximum number of milliseconds to wait
+ * @return true if the counter reached 0, false if we timed out
+ **/
+ bool await(int maxwait) {
+ auto deadline = std::chrono::steady_clock::now() + std::chrono::milliseconds(maxwait);
+ std::unique_lock<std::mutex> guard(_lock);
+ return _cond.wait_until(guard, deadline, [this]() { return (_count == 0); });
+ }
+
+ /**
+ * Obtain the current count for this latch. This method is mostly
+ * useful for debugging and testing.
+ *
+ * @return current count
+ **/
+ uint32_t getCount() const { return _count; }
+
+ /**
+ * Empty. Needs to be virtual to reduce compiler warnings.
+ **/
+ virtual ~CountDownLatch() = default;
+};
+
+} // namespace vespalib
+
diff --git a/vespalib/src/vespa/vespalib/util/gate.h b/vespalib/src/vespa/vespalib/util/gate.h
new file mode 100644
index 00000000000..7d913a7a039
--- /dev/null
+++ b/vespalib/src/vespa/vespalib/util/gate.h
@@ -0,0 +1,22 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#pragma once
+
+#include "count_down_latch.h"
+
+namespace vespalib {
+
+/**
+ * A gate is a countdown latch with an initial count of 1, indicating
+ * that we are only waiting for a single operation to complete.
+ **/
+class Gate : public CountDownLatch
+{
+public:
+ /**
+ * Sets the initial count to 1.
+ **/
+ Gate() : CountDownLatch(1) {}
+};
+
+} // namespace vespalib
diff --git a/vespalib/src/vespa/vespalib/util/simple_thread_bundle.h b/vespalib/src/vespa/vespalib/util/simple_thread_bundle.h
index 8fb7e1d04fc..4fa73c1112f 100644
--- a/vespalib/src/vespa/vespalib/util/simple_thread_bundle.h
+++ b/vespalib/src/vespa/vespalib/util/simple_thread_bundle.h
@@ -3,6 +3,7 @@
#pragma once
#include "sync.h"
+#include "count_down_latch.h"
#include "thread.h"
#include "runnable.h"
#include "thread_bundle.h"
diff --git a/vespalib/src/vespa/vespalib/util/sync.h b/vespalib/src/vespa/vespalib/util/sync.h
index c3d8ea86aec..e3f3d44122c 100644
--- a/vespalib/src/vespa/vespalib/util/sync.h
+++ b/vespalib/src/vespa/vespalib/util/sync.h
@@ -527,108 +527,5 @@ public:
}
};
-
-/**
- * A countdown latch helps one or more threads wait for the completion
- * of a number of operations performed by other threads. Specifically,
- * any thread invoking the await method will block until the countDown
- * method has been invoked an appropriate number of times. The
- * countdown latch is created with a count. Each invocation of
- * countDown will reduce the current count. When the count reaches 0,
- * the threads blocked in await will be unblocked. When the count is
- * 0, additional invocations of await will not block and additional
- * invocations of countDown will have no effect.
- **/
-class CountDownLatch
-{
-private:
- Monitor _monitor;
- uint32_t _count;
-
- CountDownLatch(const CountDownLatch &rhs) = delete;
- CountDownLatch &operator=(const CountDownLatch &rhs) = delete;
-
-public:
- /**
- * Create a countdown latch with the given initial count.
- *
- * @param cnt initial count
- **/
- CountDownLatch(uint32_t cnt) : _monitor(), _count(cnt) {}
-
- /**
- * Count down this latch. When the count reaches 0, all threads
- * blocked in the await method will be unblocked.
- **/
- void countDown() {
- MonitorGuard guard(_monitor);
- if (_count == 0) {
- return;
- }
- --_count;
- if (_count == 0) {
- guard.broadcast();
- }
- }
-
- /**
- * Wait for this latch to count down to 0. This method will block
- * until the countDown method has been invoked enough times to
- * reduce the count to 0.
- **/
- void await() {
- MonitorGuard guard(_monitor);
- while (_count != 0) {
- guard.wait();
- }
- }
-
- /**
- * Wait for this latch to count down to 0. This method will block
- * until the countDown method has been invoked enough times to
- * reduce the count to 0 or the given amount of time has elapsed.
- *
- * @param maxwait the maximum number of milliseconds to wait
- * @return true if the counter reached 0, false if we timed out
- **/
- bool await(int maxwait) {
- MonitorGuard guard(_monitor);
- TimedWaiter waiter(guard, maxwait);
- while (_count != 0 && waiter.hasTime()) {
- waiter.wait();
- }
- return (_count == 0);
- }
-
- /**
- * Obtain the current count for this latch. This method is mostly
- * useful for debugging and testing.
- *
- * @return current count
- **/
- uint32_t getCount() const {
- return _count;
- }
-
- /**
- * Empty. Needs to be virtual to reduce compiler warnings.
- **/
- virtual ~CountDownLatch() = default;
-};
-
-
-/**
- * A gate is a countdown latch with an initial count of 1, indicating
- * that we are only waiting for a single operation to complete.
- **/
-class Gate : public CountDownLatch
-{
-public:
- /**
- * Sets the initial count to 1.
- **/
- Gate() : CountDownLatch(1) {}
-};
-
} // namespace vespalib
diff --git a/vespalib/src/vespa/vespalib/util/thread.h b/vespalib/src/vespa/vespalib/util/thread.h
index 426057be85a..d24a7e6f174 100644
--- a/vespalib/src/vespa/vespalib/util/thread.h
+++ b/vespalib/src/vespa/vespalib/util/thread.h
@@ -3,6 +3,7 @@
#pragma once
#include "sync.h"
+#include "gate.h"
#include "runnable.h"
#include "active.h"
#include <vespa/fastos/thread.h>
diff --git a/vespalib/src/vespa/vespalib/util/threadstackexecutorbase.h b/vespalib/src/vespa/vespalib/util/threadstackexecutorbase.h
index 5048a9c0436..1d8545781f5 100644
--- a/vespalib/src/vespa/vespalib/util/threadstackexecutorbase.h
+++ b/vespalib/src/vespa/vespalib/util/threadstackexecutorbase.h
@@ -6,6 +6,7 @@
#include "eventbarrier.hpp"
#include "arrayqueue.hpp"
#include "sync.h"
+#include "gate.h"
#include "runnable.h"
#include <memory>
#include <vector>