aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/utils
diff options
context:
space:
mode:
authorJoel Low <[email protected]>2016-11-05 22:11:55 +0800
committerJoel Low <[email protected]>2016-11-06 12:45:14 +0800
commit54a951b6c67922b108488465bc062eda42877fd7 (patch)
treef8eaa44d52cba907698f3c34462f6d6245a8bc5b /src/lib/utils
parentc4da8e6545adb36a4c398fc3f872565e420e4aad (diff)
Implement barriers for Threaded Fork
This commit introduces a concept of a barrier, where all threads must synchronise before continuing. Threaded Fork uses this to ensure that all input is consumed by each sink exactly once. Fixes #695.
Diffstat (limited to 'src/lib/utils')
-rw-r--r--src/lib/utils/barrier.cpp35
-rw-r--r--src/lib/utils/barrier.h41
-rw-r--r--src/lib/utils/info.txt1
3 files changed, 77 insertions, 0 deletions
diff --git a/src/lib/utils/barrier.cpp b/src/lib/utils/barrier.cpp
new file mode 100644
index 000000000..eb2ab978c
--- /dev/null
+++ b/src/lib/utils/barrier.cpp
@@ -0,0 +1,35 @@
+/*
+* Barrier
+* (C) 2016 Joel Low
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/internal/barrier.h>
+
+#if defined(BOTAN_TARGET_OS_HAS_THREADS)
+
+namespace Botan {
+
+void Barrier::wait(unsigned delta)
+ {
+ lock_guard_type<mutex_type> lock(m_mutex);
+ m_value += delta;
+ }
+
+void Barrier::sync()
+ {
+ std::unique_lock<mutex_type> lock(m_mutex);
+ --m_value;
+ if(m_value > 0)
+ m_cond.wait(lock, [this] { return m_value <= 0; });
+ else
+ {
+ m_value = 0;
+ m_cond.notify_all();
+ }
+ }
+
+}
+
+#endif
diff --git a/src/lib/utils/barrier.h b/src/lib/utils/barrier.h
new file mode 100644
index 000000000..96b9c0c7b
--- /dev/null
+++ b/src/lib/utils/barrier.h
@@ -0,0 +1,41 @@
+/*
+* Barrier
+* (C) 2016 Joel Low
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_UTIL_BARRIER_H__
+#define BOTAN_UTIL_BARRIER_H__
+
+#include <botan/mutex.h>
+
+#if defined(BOTAN_TARGET_OS_HAS_THREADS)
+#include <condition_variable>
+#endif
+
+namespace Botan {
+
+#if defined(BOTAN_TARGET_OS_HAS_THREADS)
+// Barrier implements a barrier synchronization primitive. wait() will indicate
+// how many threads to synchronize; each thread needing synchronization should
+// call sync(). When sync() returns, the barrier is reset to zero.
+class Barrier
+ {
+ public:
+ explicit Barrier(int value = 0) : m_value(value) {}
+
+ void wait(unsigned delta);
+
+ void sync();
+
+ private:
+ int m_value;
+ mutex_type m_mutex;
+ std::condition_variable m_cond;
+ };
+#endif
+
+}
+
+#endif
diff --git a/src/lib/utils/info.txt b/src/lib/utils/info.txt
index 189b2da1f..75a428a83 100644
--- a/src/lib/utils/info.txt
+++ b/src/lib/utils/info.txt
@@ -22,6 +22,7 @@ version.h
</header:public>
<header:internal>
+barrier.h
bit_ops.h
ct_utils.h
donna128.h