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 #include "boost/fiber/algo/round_robin.hpp" 8 9 #include <boost/assert.hpp> 10 #include <boost/context/detail/prefetch.hpp> 11 12 #ifdef BOOST_HAS_ABI_HEADERS 13 # include BOOST_ABI_PREFIX 14 #endif 15 16 namespace boost { 17 namespace fibers { 18 namespace algo { 19 20 void awakened(context * ctx)21round_robin::awakened( context * ctx) noexcept { 22 BOOST_ASSERT( nullptr != ctx); 23 BOOST_ASSERT( ! ctx->ready_is_linked() ); 24 BOOST_ASSERT( ctx->is_resumable() ); 25 ctx->ready_link( rqueue_); 26 } 27 28 context * pick_next()29round_robin::pick_next() noexcept { 30 context * victim = nullptr; 31 if ( ! rqueue_.empty() ) { 32 victim = & rqueue_.front(); 33 rqueue_.pop_front(); 34 boost::context::detail::prefetch_range( victim, sizeof( context) ); 35 BOOST_ASSERT( nullptr != victim); 36 BOOST_ASSERT( ! victim->ready_is_linked() ); 37 BOOST_ASSERT( victim->is_resumable() ); 38 } 39 return victim; 40 } 41 42 bool has_ready_fibers() const43round_robin::has_ready_fibers() const noexcept { 44 return ! rqueue_.empty(); 45 } 46 47 void suspend_until(std::chrono::steady_clock::time_point const & time_point)48round_robin::suspend_until( std::chrono::steady_clock::time_point const& time_point) noexcept { 49 if ( (std::chrono::steady_clock::time_point::max)() == time_point) { 50 std::unique_lock< std::mutex > lk{ mtx_ }; 51 cnd_.wait( lk, [&](){ return flag_; }); 52 flag_ = false; 53 } else { 54 std::unique_lock< std::mutex > lk{ mtx_ }; 55 cnd_.wait_until( lk, time_point, [&](){ return flag_; }); 56 flag_ = false; 57 } 58 } 59 60 void notify()61round_robin::notify() noexcept { 62 std::unique_lock< std::mutex > lk{ mtx_ }; 63 flag_ = true; 64 lk.unlock(); 65 cnd_.notify_all(); 66 } 67 68 }}} 69 70 #ifdef BOOST_HAS_ABI_HEADERS 71 # include BOOST_ABI_SUFFIX 72 #endif 73