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 BOOST_FIBER_DETAIL_THREAD_BARRIER_H 8 #define BOOST_FIBER_DETAIL_THREAD_BARRIER_H 9 10 #include <cstddef> 11 #include <condition_variable> 12 #include <mutex> 13 14 #include <boost/assert.hpp> 15 #include <boost/config.hpp> 16 17 #include <boost/fiber/detail/config.hpp> 18 19 #ifdef BOOST_HAS_ABI_HEADERS 20 # include BOOST_ABI_PREFIX 21 #endif 22 23 namespace boost { 24 namespace fibers { 25 namespace detail { 26 27 class thread_barrier { 28 private: 29 std::size_t initial_; 30 std::size_t current_; 31 bool cycle_{ true }; 32 std::mutex mtx_{}; 33 std::condition_variable cond_{}; 34 35 public: thread_barrier(std::size_t initial)36 explicit thread_barrier( std::size_t initial) : 37 initial_{ initial }, 38 current_{ initial_ } { 39 BOOST_ASSERT ( 0 != initial); 40 } 41 42 thread_barrier( thread_barrier const&) = delete; 43 thread_barrier & operator=( thread_barrier const&) = delete; 44 wait()45 bool wait() { 46 std::unique_lock< std::mutex > lk( mtx_); 47 const bool cycle = cycle_; 48 if ( 0 == --current_) { 49 cycle_ = ! cycle_; 50 current_ = initial_; 51 lk.unlock(); // no pessimization 52 cond_.notify_all(); 53 return true; 54 } 55 cond_.wait( lk, [&](){ return cycle != cycle_; }); 56 return false; 57 } 58 }; 59 60 }}} 61 62 #endif // BOOST_FIBER_DETAIL_THREAD_BARRIER_H 63