]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/boost/libs/fiber/src/context.cpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / libs / fiber / src / context.cpp
index 5ad356a7133c89774182f996a224fcef58b37fed..90f9aaf0738c0b7db01868de833f7b1d80e66041 100644 (file)
@@ -118,18 +118,8 @@ context::~context() {
     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_;
@@ -202,9 +192,7 @@ context::join() {
         // 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);
     }
@@ -236,13 +224,7 @@ context::terminate() noexcept {
     // 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_) {
@@ -262,12 +244,34 @@ context::wait_until( std::chrono::steady_clock::time_point const& tp) noexcept {
 
 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);
@@ -354,11 +358,6 @@ context::terminated_is_linked() const noexcept {
     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() );
@@ -377,12 +376,6 @@ context::sleep_unlink() noexcept {
     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);