tlx
thread_barrier_mutex.hpp
Go to the documentation of this file.
1 /*******************************************************************************
2  * tlx/thread_barrier_mutex.hpp
3  *
4  * Part of tlx - http://panthema.net/tlx
5  *
6  * Copyright (C) 2015-2019 Timo Bingmann <tb@panthema.net>
7  *
8  * All rights reserved. Published under the Boost Software License, Version 1.0
9  ******************************************************************************/
10 
11 #ifndef TLX_THREAD_BARRIER_MUTEX_HEADER
12 #define TLX_THREAD_BARRIER_MUTEX_HEADER
13 
15 
16 #include <condition_variable>
17 #include <mutex>
18 
19 namespace tlx {
20 
21 /*!
22  * Implements a thread barrier using mutex locking and condition variables that
23  * can be used to synchronize threads.
24  */
26 {
27 public:
28  /*!
29  * Creates a new barrier that waits for n threads.
30  */
31  explicit ThreadBarrierMutex(size_t thread_count)
32  : thread_count_(thread_count) { }
33 
34  /*!
35  * Waits for n threads to arrive.
36  *
37  * This method blocks and returns as soon as n threads are waiting inside
38  * the method. Prior to continuing work, the lambda functor is called by the
39  * last thread entering the barrier.
40  */
41  template <typename Lambda = NoOperation<void> >
42  void wait(Lambda lambda = Lambda()) {
43  std::unique_lock<std::mutex> lock(mutex_);
44 
45  size_t current = step_;
46  counts_[current]++;
47 
48  if (counts_[current] < thread_count_) {
49  while (counts_[current] < thread_count_) {
50  cv_.wait(lock);
51  }
52  }
53  else {
54  // last thread has reached the barrier
55  step_ = step_ ? 0 : 1;
56  counts_[step_] = 0;
57  lambda();
58  cv_.notify_all();
59  }
60  }
61 
62  /*!
63  * Waits for n threads to arrive. Identical with wait() for
64  * ThreadBarrierMutex.
65  *
66  * This method blocks and returns as soon as n threads are waiting inside
67  * the method. Prior to continuing work, the lambda functor is called by the
68  * last thread entering the barrier.
69  */
70  template <typename Lambda = NoOperation<void> >
71  void wait_yield(Lambda lambda = Lambda()) {
72  return wait(lambda);
73  }
74 
75  //! return generation step bit: 0 or 1
76  size_t step() const {
77  return step_;
78  }
79 
80 protected:
81  //! number of threads
82  const size_t thread_count_;
83 
84  //! mutex to synchronize access to the counters
85  std::mutex mutex_;
86 
87  //! condition variable everyone waits on for the last thread to signal
88  std::condition_variable cv_;
89 
90  //! two counters: switch between them every run.
91  size_t counts_[2] = { 0, 0 };
92 
93  //! current counter used.
94  size_t step_ = 0;
95 };
96 
97 } // namespace tlx
98 
99 #endif // !TLX_THREAD_BARRIER_MUTEX_HEADER
100 
101 /******************************************************************************/
std::mutex mutex_
mutex to synchronize access to the counters
std::condition_variable cv_
condition variable everyone waits on for the last thread to signal
size_t step() const
return generation step bit: 0 or 1
ThreadBarrierMutex(size_t thread_count)
Creates a new barrier that waits for n threads.
void wait(Lambda lambda=Lambda())
Waits for n threads to arrive.
void wait_yield(Lambda lambda=Lambda())
Waits for n threads to arrive.
size_t counts_[2]
two counters: switch between them every run.
Implements a thread barrier using mutex locking and condition variables that can be used to synchroni...
size_t step_
current counter used.
const size_t thread_count_
number of threads