thread_barrier.hpp 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. // Copyright Oliver Kowalke 2013.
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef BOOST_FIBER_DETAIL_THREAD_BARRIER_H
  6. #define BOOST_FIBER_DETAIL_THREAD_BARRIER_H
  7. #include <cstddef>
  8. #include <condition_variable>
  9. #include <mutex>
  10. #include <boost/assert.hpp>
  11. #include <boost/config.hpp>
  12. #include <boost/fiber/detail/config.hpp>
  13. #ifdef BOOST_HAS_ABI_HEADERS
  14. # include BOOST_ABI_PREFIX
  15. #endif
  16. namespace boost {
  17. namespace fibers {
  18. namespace detail {
  19. class thread_barrier {
  20. private:
  21. std::size_t initial_;
  22. std::size_t current_;
  23. bool cycle_{ true };
  24. std::mutex mtx_{};
  25. std::condition_variable cond_{};
  26. public:
  27. explicit thread_barrier( std::size_t initial) :
  28. initial_{ initial },
  29. current_{ initial_ } {
  30. BOOST_ASSERT ( 0 != initial);
  31. }
  32. thread_barrier( thread_barrier const&) = delete;
  33. thread_barrier & operator=( thread_barrier const&) = delete;
  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 // BOOST_FIBER_DETAIL_THREAD_BARRIER_H