diff options
author | Joel Low <[email protected]> | 2016-11-05 22:11:55 +0800 |
---|---|---|
committer | Joel Low <[email protected]> | 2016-11-06 12:45:14 +0800 |
commit | 54a951b6c67922b108488465bc062eda42877fd7 (patch) | |
tree | f8eaa44d52cba907698f3c34462f6d6245a8bc5b /src/lib/utils | |
parent | c4da8e6545adb36a4c398fc3f872565e420e4aad (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.cpp | 35 | ||||
-rw-r--r-- | src/lib/utils/barrier.h | 41 | ||||
-rw-r--r-- | src/lib/utils/info.txt | 1 |
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 |