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: barrier(std::size_t initial)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 wait()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 51