boost::context::continuation scheduler::dispatch() noexcept { BOOST_ASSERT( context::active() == dispatcher_ctx_); for (;;) { if ( shutdown_) { // notify sched-algorithm about termination algo_->notify(); if ( worker_queue_.empty() ) { break; } } // release terminated context' release_terminated_(); #if ! defined(BOOST_FIBERS_NO_ATOMICS) // get context' from remote ready-queue remote_ready2ready_(); #endif // get sleeping context' sleep2ready_(); // get next ready context context * ctx = algo_->pick_next(); if ( nullptr != ctx) { BOOST_ASSERT( ctx->is_resumable() ); BOOST_ASSERT( ! ctx->ready_is_linked() ); #if ! defined(BOOST_FIBERS_NO_ATOMICS) BOOST_ASSERT( ! ctx->remote_ready_is_linked() ); #endif BOOST_ASSERT( ! ctx->sleep_is_linked() ); BOOST_ASSERT( ! ctx->terminated_is_linked() ); // no test for '! ctx->wait_is_linked()' because // context is registered in wait-queue of sync. primitives // via wait_for()/wait_until() // push dispatcher-context to ready-queue // so that ready-queue never becomes empty ctx->resume( dispatcher_ctx_.get() ); BOOST_ASSERT( context::active() == dispatcher_ctx_.get() ); } else { // no ready context, wait till signaled // set deadline to highest value std::chrono::steady_clock::time_point suspend_time = (std::chrono::steady_clock::time_point::max)(); // get lowest deadline from sleep-queue sleep_queue_type::iterator i = sleep_queue_.begin(); if ( sleep_queue_.end() != i) { suspend_time = i->tp_; } // no ready context, wait till signaled algo_->suspend_until( suspend_time); } } // release termianted context' release_terminated_(); // return to main-context return main_ctx_->suspend_with_cc(); }
void scheduler::dispatch() noexcept { #else boost::context::execution_context< detail::data_t * > scheduler::dispatch() noexcept { #endif BOOST_ASSERT( context::active() == dispatcher_ctx_); for (;;) { bool no_worker = worker_queue_.empty(); if ( shutdown_) { // notify sched-algorithm about termination algo_->notify(); if ( no_worker) { break; } } // release terminated context' release_terminated_(); // get context' from remote ready-queue remote_ready2ready_(); // get sleeping context' sleep2ready_(); // get next ready context context * ctx = get_next_(); if ( nullptr != ctx) { // push dispatcher-context to ready-queue // so that ready-queue never becomes empty ctx->resume( dispatcher_ctx_.get() ); BOOST_ASSERT( context::active() == dispatcher_ctx_.get() ); } else { // no ready context, wait till signaled // set deadline to highest value std::chrono::steady_clock::time_point suspend_time = (std::chrono::steady_clock::time_point::max)(); // get lowest deadline from sleep-queue sleep_queue_t::iterator i = sleep_queue_.begin(); if ( sleep_queue_.end() != i) { suspend_time = i->tp_; } // no ready context, wait till signaled algo_->suspend_until( suspend_time); } } // release termianted context' release_terminated_(); // return to main-context #if (BOOST_EXECUTION_CONTEXT==1) main_ctx_->resume(); #else return main_ctx_->suspend_with_cc(); #endif }