diff options
author | Joel Low <[email protected]> | 2016-11-06 14:04:37 +0800 |
---|---|---|
committer | Joel Low <[email protected]> | 2016-11-06 14:04:37 +0800 |
commit | 6a00ecd2c027c884da509bce22b1d8a72c3be928 (patch) | |
tree | 24162fde15a7150f9ed13d3dd9e47b5c88215866 /src | |
parent | a914a872aab38e62bc838967cd7d310c6e022901 (diff) |
Keep track of the number of synchronisations achieved
This allows wait() to be called immediately after sync() returns, even if not
all of the waiting threads have awoken.
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/utils/barrier.cpp | 6 | ||||
-rw-r--r-- | src/lib/utils/barrier.h | 8 |
2 files changed, 11 insertions, 3 deletions
diff --git a/src/lib/utils/barrier.cpp b/src/lib/utils/barrier.cpp index eb2ab978c..81c578b72 100644 --- a/src/lib/utils/barrier.cpp +++ b/src/lib/utils/barrier.cpp @@ -22,10 +22,14 @@ 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; }); + { + unsigned current_syncs = m_syncs; + m_cond.wait(lock, [this, ¤t_syncs] { return m_syncs != current_syncs; }); + } else { m_value = 0; + ++m_syncs; m_cond.notify_all(); } } diff --git a/src/lib/utils/barrier.h b/src/lib/utils/barrier.h index 96b9c0c7b..6d5cf9e58 100644 --- a/src/lib/utils/barrier.h +++ b/src/lib/utils/barrier.h @@ -19,11 +19,14 @@ 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. +// call sync(). When sync() returns, the barrier is reset to zero, and the +// m_syncs counter is incremented. m_syncs is a counter to ensure that wait() +// can be called after a sync() even if the previously sleeping threads have +// not awoken.) class Barrier { public: - explicit Barrier(int value = 0) : m_value(value) {} + explicit Barrier(int value = 0) : m_value(value), m_syncs(0) {} void wait(unsigned delta); @@ -31,6 +34,7 @@ class Barrier private: int m_value; + unsigned m_syncs; mutex_type m_mutex; std::condition_variable m_cond; }; |