aboutsummaryrefslogtreecommitdiff
path: root/latch.h
diff options
context:
space:
mode:
authorJohannes Stoelp <johannes.stoelp@gmail.com>2023-11-08 00:14:42 +0100
committerJohannes Stoelp <johannes.stoelp@gmail.com>2023-11-08 00:14:42 +0100
commit7a91597392c64ec8bd2b3cdfc44df98b928f41d3 (patch)
tree85bef5dd86696c742e87d0b61a0034f73789a1ac /latch.h
parent1cf1cbdeb6542bd84631aad950c02d951af319a4 (diff)
downloadcpp-utils-7a91597392c64ec8bd2b3cdfc44df98b928f41d3.tar.gz
cpp-utils-7a91597392c64ec8bd2b3cdfc44df98b928f41d3.zip
latch: add simple latch based on a mutex and cv
Diffstat (limited to 'latch.h')
-rw-r--r--latch.h41
1 files changed, 41 insertions, 0 deletions
diff --git a/latch.h b/latch.h
new file mode 100644
index 0000000..ec2006e
--- /dev/null
+++ b/latch.h
@@ -0,0 +1,41 @@
+#ifndef UTILS_TIMER_H
+#define UTILS_TIMER_H
+
+#include <condition_variable>
+#include <mutex>
+
+#include <cassert>
+
+/// latch
+///
+/// A simple one-shot latch based on a mutex and condition variable.
+///
+/// The latch is initialized with a number N of threads to wait for. Different
+/// threads can call arrive_and_wait() on the latch. Those threads enter a wait
+/// state until the Nth thread calls arrive_and_wait(), which then releases all
+/// threads at the same time.
+struct latch {
+ explicit latch(std::size_t cnt) : m_cnt{cnt} {}
+ ~latch() {
+ assert(m_cnt == 0);
+ }
+
+ void arrive_and_wait() {
+ std::unique_lock<std::mutex> lk(m_mtx);
+ m_cnt -= 1;
+
+ if (m_cnt != 0) {
+ m_cv.wait(lk, [this]() { return m_cnt == 0; });
+ } else {
+ m_cv.notify_all();
+ }
+ }
+
+ private:
+ std::size_t m_cnt;
+
+ std::mutex m_mtx;
+ std::condition_variable m_cv;
+};
+
+#endif