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
19namespace tlx {
20
21/*!
22 * Implements a thread barrier using mutex locking and condition variables that
23 * can be used to synchronize threads.
24 */
26{
27public:
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
80protected:
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/******************************************************************************/
Implements a thread barrier using mutex locking and condition variables that can be used to synchroni...
size_t step_
current counter used.
void wait_yield(Lambda lambda=Lambda())
Waits for n threads to arrive.
std::mutex mutex_
mutex to synchronize access to the counters
size_t step() const
return generation step bit: 0 or 1
std::condition_variable cv_
condition variable everyone waits on for the last thread to signal
const size_t thread_count_
number of threads
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.
size_t counts_[2]
two counters: switch between them every run.