aboutsummaryrefslogblamecommitdiff
path: root/latch.h
blob: ec2006e38075c4c720d119b2cfe3826ae9c2ad7f (plain) (tree)








































                                                                               
#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