]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | |
2 | // Copyright Oliver Kowalke 2013. | |
3 | // Distributed under the Boost Software License, Version 1.0. | |
4 | // (See accompanying file LICENSE_1_0.txt or copy at | |
5 | // http://www.boost.org/LICENSE_1_0.txt) | |
6 | ||
7 | #ifndef BARRIER_H | |
8 | #define BARRIER_H | |
9 | ||
10 | #include <cstddef> | |
11 | #include <condition_variable> | |
12 | #include <mutex> | |
13 | ||
14 | #include <boost/assert.hpp> | |
15 | ||
16 | class barrier { | |
17 | private: | |
18 | std::size_t initial_; | |
19 | std::size_t current_; | |
20 | bool cycle_{ true }; | |
21 | std::mutex mtx_{}; | |
22 | std::condition_variable cond_{}; | |
23 | ||
24 | public: | |
25 | explicit barrier( std::size_t initial) : | |
26 | initial_{ initial }, | |
27 | current_{ initial_ } { | |
28 | BOOST_ASSERT ( 0 != initial); | |
29 | } | |
30 | ||
31 | barrier( barrier const&) = delete; | |
32 | barrier & operator=( barrier const&) = delete; | |
33 | ||
34 | bool wait() { | |
35 | std::unique_lock< std::mutex > lk( mtx_); | |
36 | const bool cycle = cycle_; | |
37 | if ( 0 == --current_) { | |
38 | cycle_ = ! cycle_; | |
39 | current_ = initial_; | |
40 | lk.unlock(); // no pessimization | |
41 | cond_.notify_all(); | |
42 | return true; | |
43 | } else { | |
44 | cond_.wait( lk, [&](){ return cycle != cycle_; }); | |
45 | } | |
46 | return false; | |
47 | } | |
48 | }; | |
49 | ||
50 | #endif // BARRIER_H |