BOOST_ASSERT( ! ready_is_linked() );
BOOST_ASSERT( ! remote_ready_is_linked() );
BOOST_ASSERT( ! sleep_is_linked() );
- BOOST_ASSERT( ! wait_is_linked() );
if ( is_context( type::dispatcher_context) ) {
- // dispatcher-context is resumed by main-context
- // while the scheduler is deconstructed
-#ifdef BOOST_DISABLE_ASSERTS
- wait_queue_.pop_front();
-#else
- context * ctx = & wait_queue_.front();
- wait_queue_.pop_front();
- BOOST_ASSERT( ctx->is_context( type::main_context) );
BOOST_ASSERT( nullptr == active() );
-#endif
}
BOOST_ASSERT( wait_queue_.empty() );
delete properties_;
// push active context to wait-queue, member
// of the context which has to be joined by
// the active context
- active_ctx->wait_link( wait_queue_);
- // suspend active context
- active_ctx->get_scheduler()->suspend( lk);
+ wait_queue_.suspend_and_wait( lk, active_ctx);
// active context resumed
BOOST_ASSERT( context::active() == active_ctx);
}
// mark as terminated
terminated_ = true;
// notify all waiting fibers
- while ( ! wait_queue_.empty() ) {
- context * ctx = & wait_queue_.front();
- // remove fiber from wait-queue
- wait_queue_.pop_front();
- // notify scheduler
- schedule( ctx);
- }
+ wait_queue_.notify_all();
BOOST_ASSERT( wait_queue_.empty() );
// release fiber-specific-data
for ( fss_data_t::value_type & data : fss_data_) {
bool
context::wait_until( std::chrono::steady_clock::time_point const& tp,
- detail::spinlock_lock & lk) noexcept {
+ detail::spinlock_lock & lk,
+ waker && w) noexcept {
BOOST_ASSERT( nullptr != get_scheduler() );
BOOST_ASSERT( this == active() );
- return get_scheduler()->wait_until( this, tp, lk);
+ return get_scheduler()->wait_until( this, tp, lk, std::move(w));
+}
+
+
+bool context::wake(const size_t epoch) noexcept
+{
+ size_t expected = epoch;
+ bool is_last_waker = waker_epoch_.compare_exchange_strong(expected, epoch + 1, std::memory_order_acq_rel);
+ if ( ! is_last_waker) {
+ // waker_epoch_ has been incremented before, so consider this wake
+ // operation as outdated and do nothing
+ return false;
+ }
+
+ BOOST_ASSERT( context::active() != this);
+ if ( context::active()->get_scheduler() == get_scheduler()) {
+ get_scheduler()->schedule( this);
+ } else {
+ get_scheduler()->schedule_from_remote( this);
+ }
+ return true;
}
+
void
context::schedule( context * ctx) noexcept {
//BOOST_ASSERT( nullptr != ctx);
return terminated_hook_.is_linked();
}
-bool
-context::wait_is_linked() const noexcept {
- return wait_hook_.is_linked();
-}
-
void
context::worker_unlink() noexcept {
BOOST_ASSERT( worker_is_linked() );
sleep_hook_.unlink();
}
-void
-context::wait_unlink() noexcept {
- BOOST_ASSERT( wait_is_linked() );
- wait_hook_.unlink();
-}
-
void
context::detach() noexcept {
BOOST_ASSERT( context::active() != this);