aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJoel Low <[email protected]>2016-11-06 14:04:37 +0800
committerJoel Low <[email protected]>2016-11-06 14:04:37 +0800
commit6a00ecd2c027c884da509bce22b1d8a72c3be928 (patch)
tree24162fde15a7150f9ed13d3dd9e47b5c88215866 /src
parenta914a872aab38e62bc838967cd7d310c6e022901 (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.cpp6
-rw-r--r--src/lib/utils/barrier.h8
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, &current_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;
};