diff --git a/include/boost/fiber/condition.hpp b/include/boost/fiber/condition.hpp index f50e7d05..a0c61014 100644 --- a/include/boost/fiber/condition.hpp +++ b/include/boost/fiber/condition.hpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -62,7 +63,7 @@ public: template< typename LockType > void wait( LockType & lt) { - fiber_context * f( detail::scheduler::instance()->active() ); + fiber_context * f( fiber_context::active() ); try { // lock spinlock detail::spinlock_lock lk( splk_); @@ -77,8 +78,8 @@ public: // suspend this fiber // locked spinlock will be released if this fiber - // was stored inside schedulers's waiting-queue - detail::scheduler::instance()->wait( lk); + // was stored inside manager's waiting-queue + fiber_context::active()->do_wait( lk); // lock external again before returning lt.lock(); @@ -97,7 +98,7 @@ public: cv_status wait_until( LockType & lt, std::chrono::time_point< Clock, Duration > const& timeout_time) { cv_status status = cv_status::no_timeout; - fiber_context * f( detail::scheduler::instance()->active() ); + fiber_context * f( fiber_context::active() ); try { // lock spinlock detail::spinlock_lock lk( splk_); @@ -111,8 +112,8 @@ public: // suspend this fiber // locked spinlock will be released if this fiber - // was stored inside schedulers's waiting-queue - if ( ! detail::scheduler::instance()->wait_until( timeout_time, lk) ) { + // was stored inside manager's waiting-queue + if ( ! fiber_context::active()->do_wait_until( timeout_time, lk) ) { // this fiber was not notified before timeout // lock spinlock again detail::spinlock_lock lk( splk_); diff --git a/include/boost/fiber/detail/scheduler.hpp b/include/boost/fiber/detail/scheduler.hpp deleted file mode 100644 index 5b3f8d3b..00000000 --- a/include/boost/fiber/detail/scheduler.hpp +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright Oliver Kowalke 2013. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_FIBERS_DETAIL_SCHEDULER_H -#define BOOST_FIBERS_DETAIL_SCHEDULER_H - -#include -#include - -#include -#include - -#include -#include -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -namespace boost { -namespace fibers { - -class fiber_context; - -namespace detail { - -struct scheduler { - scheduler( scheduler const&) = delete; - scheduler & operator=( scheduler const&) = delete; - - template< typename F > - static fiber_context * extract( F const& f) noexcept { - return const_cast< F & >( f).impl_.get(); - } - - static fiber_manager * instance() noexcept { - static thread_local fiber_manager mgr; - return & mgr; - } - - static void replace( std::unique_ptr< sched_algorithm > other) { - BOOST_ASSERT( nullptr != other); - - instance()->set_sched_algo( std::move( other) ); - } -}; - -}}} - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -#endif // BOOST_FIBERS_DETAIL_SCHEDULER_H diff --git a/include/boost/fiber/detail/waiting_queue.hpp b/include/boost/fiber/detail/waiting_queue.hpp index 87c38b91..51d2be9a 100644 --- a/include/boost/fiber/detail/waiting_queue.hpp +++ b/include/boost/fiber/detail/waiting_queue.hpp @@ -8,7 +8,6 @@ #define BOOST_FIBERS_DETAIL_WAITING_QUEUE_H #include -#include #include #include @@ -49,7 +48,7 @@ public: return head_; } - void move_to( std::unique_ptr< sched_algorithm > &); + void move_to( sched_algorithm *); void interrupt_all() noexcept; diff --git a/include/boost/fiber/fiber.hpp b/include/boost/fiber/fiber.hpp index 9e20569c..78dd0e7a 100644 --- a/include/boost/fiber/fiber.hpp +++ b/include/boost/fiber/fiber.hpp @@ -21,7 +21,6 @@ #include #include #include -#include #ifdef BOOST_HAS_ABI_HEADERS # include BOOST_ABI_PREFIX @@ -34,7 +33,7 @@ class fiber_context; class BOOST_FIBERS_DECL fiber { private: - friend struct detail::scheduler; + friend class fiber_context; typedef intrusive_ptr< fiber_context > ptr_t; diff --git a/include/boost/fiber/fiber_context.hpp b/include/boost/fiber/fiber_context.hpp index 26ef1e0d..2d59f766 100644 --- a/include/boost/fiber/fiber_context.hpp +++ b/include/boost/fiber/fiber_context.hpp @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -38,6 +37,7 @@ namespace boost { namespace fibers { +class fiber; class fiber_properties; class BOOST_FIBERS_DECL fiber_context { @@ -79,6 +79,8 @@ private: typedef std::map< uintptr_t, fss_data > fss_data_t; + static thread_local fiber_context * active_; + #if ! defined(BOOST_FIBERS_NO_ATOMICS) std::atomic< std::size_t > use_count_; std::atomic< fiber_status > state_; @@ -89,6 +91,7 @@ private: int flags_; #endif detail::spinlock splk_; + fiber_manager * mgr_; context::execution_context ctx_; fss_data_t fss_data_; std::vector< fiber_context * > waiting_; @@ -96,21 +99,6 @@ private: std::chrono::steady_clock::time_point tp_; fiber_properties * properties_; - // main fiber - fiber_context() : - use_count_( 1), // allocated on stack - state_( fiber_status::running), - flags_( flag_main_fiber), - splk_(), - ctx_( context::execution_context::current() ), - fss_data_(), - waiting_(), - except_(), - tp_( (std::chrono::steady_clock::time_point::max)() ), - properties_( nullptr), - nxt( nullptr) { - } - protected: virtual void deallocate() { } @@ -172,9 +160,27 @@ public: } }; + static fiber_context * active() noexcept; + + static fiber_context * active( fiber_context * active) noexcept; + fiber_context * nxt; - static fiber_context * main_fiber(); + // main fiber + fiber_context() : + use_count_( 1), // allocated on stack + state_( fiber_status::running), + flags_( flag_main_fiber), + splk_(), + mgr_( nullptr), + ctx_( context::execution_context::current() ), + fss_data_(), + waiting_(), + except_(), + tp_( (std::chrono::steady_clock::time_point::max)() ), + properties_( nullptr), + nxt( nullptr) { + } // worker fiber template< typename StackAlloc, typename Fn, typename ... Args > @@ -186,6 +192,7 @@ public: state_( fiber_status::ready), flags_( 0), splk_(), + mgr_( nullptr), ctx_( palloc, salloc, // lambda, executed in execution context // mutable: generated operator() is not const -> enables std::move( fn) @@ -208,7 +215,7 @@ public: release(); // switch to another fiber - detail::scheduler::instance()->run(); + do_schedule(); BOOST_ASSERT_MSG( false, "fiber already terminated"); }), @@ -222,6 +229,15 @@ public: virtual ~fiber_context(); + void manager( fiber_manager * mgr) { + BOOST_ASSERT( nullptr != mgr); + mgr_ = mgr; + } + + fiber_manager * manager() const noexcept { + return mgr_; + } + id get_id() const noexcept { return id( const_cast< fiber_context * >( this) ); } @@ -342,6 +358,39 @@ public: void release(); + void do_spawn( fiber const&); + + void do_schedule(); + + void do_wait( detail::spinlock_lock &); + + template< typename Clock, typename Duration > + bool do_wait_until( std::chrono::time_point< Clock, Duration > const& timeout_time, + detail::spinlock_lock & lk) { + return mgr_->wait_until( timeout_time, lk); + } + + template< typename Rep, typename Period > + bool do_wait_for( std::chrono::duration< Rep, Period > const& timeout_duration, + detail::spinlock_lock & lk) { + return mgr_->wait_for( timeout_duration, lk); + } + + void do_yield(); + + void do_join( fiber_context *); + + std::size_t do_ready_fibers() const noexcept; + + void do_set_sched_algo( std::unique_ptr< sched_algorithm >); + + template< typename Rep, typename Period > + void do_wait_interval( std::chrono::duration< Rep, Period > const& wait_interval) noexcept { + mgr_->wait_interval( wait_interval); + } + + std::chrono::steady_clock::duration do_wait_interval() noexcept; + friend void intrusive_ptr_add_ref( fiber_context * f) { BOOST_ASSERT( nullptr != f); ++f->use_count_; diff --git a/include/boost/fiber/fiber_manager.hpp b/include/boost/fiber/fiber_manager.hpp index 35c2bed3..1c7471cf 100644 --- a/include/boost/fiber/fiber_manager.hpp +++ b/include/boost/fiber/fiber_manager.hpp @@ -36,7 +36,6 @@ private: typedef detail::terminated_queue tqueue_t; std::unique_ptr< sched_algorithm > sched_algo_; - fiber_context * active_fiber_; wqueue_t wqueue_; tqueue_t tqueue_; std::chrono::steady_clock::duration wait_interval_; @@ -79,12 +78,8 @@ public: void join( fiber_context *); - fiber_context * active() noexcept; - std::size_t ready_fibers() const noexcept; - sched_algorithm* get_sched_algo_(); - void set_sched_algo( std::unique_ptr< sched_algorithm >); void wait_interval( std::chrono::steady_clock::duration const&) noexcept; diff --git a/include/boost/fiber/fss.hpp b/include/boost/fiber/fss.hpp index 5329e289..3395a74e 100644 --- a/include/boost/fiber/fss.hpp +++ b/include/boost/fiber/fss.hpp @@ -16,6 +16,7 @@ #include #include +#include #ifdef BOOST_HAS_ABI_HEADERS # include BOOST_ABI_PREFIX @@ -61,8 +62,9 @@ public: } ~fiber_specific_ptr() { - if ( detail::scheduler::instance()->active() ) { - detail::scheduler::instance()->active()->set_fss_data( + fiber_context * f( fiber_context::active() ); + if ( nullptr != f) { + f->set_fss_data( this, cleanup_fn_, nullptr, true); } } @@ -71,9 +73,9 @@ public: fiber_specific_ptr & operator=( fiber_specific_ptr const&) = delete; T * get() const { - BOOST_ASSERT( detail::scheduler::instance()->active() ); + BOOST_ASSERT( fiber_context::active() ); - void * vp( detail::scheduler::instance()->active()->get_fss_data( this) ); + void * vp( fiber_context::active()->get_fss_data( this) ); return static_cast< T * >( vp); } @@ -87,7 +89,7 @@ public: T * release() { T * tmp = get(); - detail::scheduler::instance()->active()->set_fss_data( + fiber_context::active()->set_fss_data( this, cleanup_fn_, nullptr, false); return tmp; } @@ -95,7 +97,7 @@ public: void reset( T * t) { T * c = get(); if ( c != t) { - detail::scheduler::instance()->active()->set_fss_data( + fiber_context::active()->set_fss_data( this, cleanup_fn_, t, true); } } diff --git a/include/boost/fiber/operations.hpp b/include/boost/fiber/operations.hpp index 8647ca61..8d90ba11 100644 --- a/include/boost/fiber/operations.hpp +++ b/include/boost/fiber/operations.hpp @@ -15,9 +15,9 @@ #include #include -#include #include #include +#include #include #ifdef BOOST_HAS_ABI_HEADERS @@ -29,19 +29,19 @@ namespace this_fiber { inline fibers::fiber::id get_id() noexcept { - return fibers::detail::scheduler::instance()->active()->get_id(); + return fibers::fiber_context::active()->get_id(); } inline void yield() { - fibers::detail::scheduler::instance()->yield(); + fibers::fiber_context::active()->do_yield(); } template< typename Clock, typename Duration > void sleep_until( std::chrono::time_point< Clock, Duration > const& sleep_time) { fibers::detail::spinlock splk; std::unique_lock< fibers::detail::spinlock > lk( splk); - fibers::detail::scheduler::instance()->wait_until( sleep_time, lk); + fibers::fiber_context::active()->do_wait_until( sleep_time, lk); // check if fiber was interrupted interruption_point(); @@ -54,8 +54,8 @@ void sleep_for( std::chrono::duration< Rep, Period > const& timeout_duration) { template< typename PROPS > PROPS & properties() { - fibers::fiber_properties* props = - fibers::detail::scheduler::instance()->active()->get_properties(); + fibers::fiber_properties * props = + fibers::fiber_context::active()->get_properties(); if ( ! props) { // props could be nullptr if the thread's main fiber has not yet // yielded (not yet passed through sched_algorithm_with_properties:: @@ -64,8 +64,8 @@ PROPS & properties() { // Try again to obtain the fiber_properties subclass instance ptr. // Walk through the whole chain again because who knows WHAT might // have happened while we were yielding! - props = fibers::detail::scheduler::instance()->active()->get_properties(); - // Could still be hosed if the running scheduler isn't a subclass of + props = fibers::fiber_context::active()->get_properties(); + // Could still be hosed if the running manager isn't a subclass of // sched_algorithm_with_properties. BOOST_ASSERT_MSG(props, "this_fiber::properties not set"); } @@ -78,33 +78,33 @@ namespace fibers { inline void migrate( fiber const& f) { - detail::scheduler::instance()->spawn( detail::scheduler::extract( f) ); + fiber_context::active()->do_spawn( f); } template< typename SchedAlgo, typename ... Args > void use_scheduling_algorithm( Args && ... args) { - detail::scheduler::replace( + fiber_context::active()->do_set_sched_algo( std::make_unique< SchedAlgo >( std::forward< Args >( args) ... ) ); } template< typename Rep, typename Period > void wait_interval( std::chrono::duration< Rep, Period > const& wait_interval) noexcept { - detail::scheduler::instance()->wait_interval( wait_interval); + fiber_context::active()->do_wait_interval( wait_interval); } inline std::chrono::steady_clock::duration wait_interval() noexcept { - return detail::scheduler::instance()->wait_interval(); + return fiber_context::active()->do_wait_interval(); } template< typename Rep, typename Period > std::chrono::duration< Rep, Period > wait_interval() noexcept { - return detail::scheduler::instance()->wait_interval< Rep, Period >(); + return fiber_context::active()->do_wait_interval< Rep, Period >(); } inline std::size_t ready_fibers() { - return detail::scheduler::instance()->ready_fibers(); + return fiber_context::active()->do_ready_fibers(); } }} diff --git a/src/detail/spinlock.cpp b/src/detail/spinlock.cpp index 0d6f3d4e..ad666c2e 100644 --- a/src/detail/spinlock.cpp +++ b/src/detail/spinlock.cpp @@ -8,7 +8,6 @@ #include -#include "boost/fiber/detail/scheduler.hpp" #include "boost/fiber/fiber_context.hpp" #include "boost/fiber/fiber_manager.hpp" @@ -28,7 +27,7 @@ atomic_spinlock::lock() { // sucessive acccess to state_ -> cache hit while ( atomic_spinlock_status::locked == state_.load( std::memory_order_relaxed) ) { // busy-wait - scheduler::instance()->yield(); + fiber_context::active()->do_yield(); } // state_ was released by other fiber // cached copies are invalidated -> cache miss diff --git a/src/detail/waiting_queue.cpp b/src/detail/waiting_queue.cpp index 1ba291c8..445d8293 100644 --- a/src/detail/waiting_queue.cpp +++ b/src/detail/waiting_queue.cpp @@ -40,7 +40,7 @@ waiting_queue::push( fiber_context * item) noexcept { } void -waiting_queue::move_to( std::unique_ptr< sched_algorithm > & sched_algo) { +waiting_queue::move_to( sched_algorithm * sched_algo) { BOOST_ASSERT( nullptr != sched_algo); std::chrono::steady_clock::time_point now( @@ -91,11 +91,8 @@ waiting_queue::move_to( std::unique_ptr< sched_algorithm > & sched_algo) { void waiting_queue::interrupt_all() noexcept { - fiber_context * mf( fiber_context::main_fiber() ); for ( fiber_context * f( head_); nullptr != f; f = f->nxt) { - if ( f != mf) { - f->request_interruption( true); - } + f->request_interruption( true); } } diff --git a/src/fiber.cpp b/src/fiber.cpp index 57e1cd41..75e7b948 100644 --- a/src/fiber.cpp +++ b/src/fiber.cpp @@ -24,7 +24,7 @@ namespace fibers { void fiber::start_() { impl_->set_ready(); - detail::scheduler::instance()->spawn( impl_.get() ); + fiber_context::active()->do_spawn( * this); } void @@ -41,7 +41,7 @@ fiber::join() { "boost fiber: fiber not joinable"); } - detail::scheduler::instance()->join( impl_.get() ); + fiber_context::active()->do_join( impl_.get() ); // check if joined fiber was interrupted std::exception_ptr except( impl_->get_exception() ); diff --git a/src/fiber_context.cpp b/src/fiber_context.cpp index 8e27ebee..7d837799 100644 --- a/src/fiber_context.cpp +++ b/src/fiber_context.cpp @@ -6,8 +6,9 @@ #include "boost/fiber/fiber_context.hpp" -#include "boost/fiber/detail/scheduler.hpp" +#include "boost/fiber/algorithm.hpp" #include "boost/fiber/exceptions.hpp" +#include "boost/fiber/fiber.hpp" #include "boost/fiber/properties.hpp" #ifdef BOOST_HAS_ABI_HEADERS @@ -17,15 +18,32 @@ namespace boost { namespace fibers { -fiber_context::~fiber_context() { - BOOST_ASSERT( waiting_.empty() ); - delete properties_; +static fiber_context * main_fiber() { + static thread_local fiber_context mf; + static thread_local fiber_manager mgr; + mf.manager( & mgr); + return & mf; +} + +thread_local fiber_context * +fiber_context::active_ = main_fiber(); + +fiber_context * +fiber_context::active() noexcept { + return active_; } fiber_context * -fiber_context::main_fiber() { - static thread_local fiber_context mf; - return & mf; +fiber_context::active( fiber_context * active) noexcept { + BOOST_ASSERT( nullptr != active); + fiber_context * old( active_); + active_ = active; + return old; +} + +fiber_context::~fiber_context() { + BOOST_ASSERT( waiting_.empty() ); + delete properties_; } void @@ -128,6 +146,73 @@ fiber_context::set_properties( fiber_properties * props) { properties_ = props; } +void +fiber_context::do_spawn( fiber const& f_) { + BOOST_ASSERT( nullptr != mgr_); + BOOST_ASSERT( this == active_); + + fiber_context * f( f_.impl_.get() ); + f->manager( mgr_); + mgr_->spawn( f); +} + +void +fiber_context::do_schedule() { + BOOST_ASSERT( nullptr != mgr_); + BOOST_ASSERT( this == active_); + + mgr_->run(); +} + +void +fiber_context::do_wait( detail::spinlock_lock & lk) { + BOOST_ASSERT( nullptr != mgr_); + BOOST_ASSERT( this == active_); + + mgr_->wait( lk); +} + +void +fiber_context::do_yield() { + BOOST_ASSERT( nullptr != mgr_); + BOOST_ASSERT( this == active_); + + mgr_->yield(); +} + +void +fiber_context::do_join( fiber_context * f) { + BOOST_ASSERT( nullptr != mgr_); + BOOST_ASSERT( this == active_); + BOOST_ASSERT( nullptr != f); + + mgr_->join( f); +} + +std::size_t +fiber_context::do_ready_fibers() const noexcept { + BOOST_ASSERT( nullptr != mgr_); + BOOST_ASSERT( this == active_); + + return mgr_->ready_fibers(); +} + +void +fiber_context::do_set_sched_algo( std::unique_ptr< sched_algorithm > algo) { + BOOST_ASSERT( nullptr != mgr_); + BOOST_ASSERT( this == active_); + + mgr_->set_sched_algo( std::move( algo) ); +} + +std::chrono::steady_clock::duration +fiber_context::do_wait_interval() noexcept { + BOOST_ASSERT( nullptr != mgr_); + BOOST_ASSERT( this == active_); + + return mgr_->wait_interval(); +} + }} #ifdef BOOST_HAS_ABI_HEADERS diff --git a/src/fiber_manager.cpp b/src/fiber_manager.cpp index d4832ed6..4ca9640b 100644 --- a/src/fiber_manager.cpp +++ b/src/fiber_manager.cpp @@ -13,7 +13,6 @@ #include #include "boost/fiber/algorithm.hpp" -#include "boost/fiber/detail/scheduler.hpp" #include "boost/fiber/exceptions.hpp" #include "boost/fiber/fiber_context.hpp" #include "boost/fiber/interruption.hpp" @@ -28,15 +27,13 @@ namespace fibers { fiber_manager::fiber_manager() noexcept : sched_algo_( new round_robin() ), - active_fiber_( fiber_context::main_fiber() ), wqueue_(), tqueue_(), wait_interval_( std::chrono::milliseconds( 10) ) { } fiber_manager::~fiber_manager() noexcept { - // destructor must run in the main-fiber - BOOST_ASSERT( fiber_context::main_fiber() == active_fiber_); + // FIXME: test for main-fiber for (;;) { // NOTE: at this stage the fibers in the waiting-queue // can only be detached fibers @@ -44,19 +41,21 @@ fiber_manager::~fiber_manager() noexcept { wqueue_.interrupt_all(); // move all fibers which are ready (state_ready) // from waiting-queue to the runnable-queue - wqueue_.move_to( sched_algo_); + wqueue_.move_to( sched_algo_.get() ); // pop new fiber from ready-queue fiber_context * f( sched_algo_->pick_next() ); if ( f) { BOOST_ASSERT_MSG( f->is_ready(), "fiber with invalid state in ready-queue"); + // set fiber_manager + f->manager( this); // add active-fiber to joinig-list of f // fiber::join() should not fail because fiber f is in state_ready // so main-fiber should be in the waiting-queue of fiber f - f->join( active_fiber_); + f->join( fiber_context::active() ); // set main-fiber to state_waiting - active_fiber_->set_waiting(); + fiber_context::active()->set_waiting(); // push main-fiber to waiting-queue - wqueue_.push( active_fiber_); + wqueue_.push( fiber_context::active() ); // resume fiber f resume_( f); } else if ( wqueue_.empty() ) { @@ -65,9 +64,7 @@ fiber_manager::~fiber_manager() noexcept { } } BOOST_ASSERT( wqueue_.empty() ); - // destructor must run in the main-fiber - BOOST_ASSERT( fiber_context::main_fiber() == active_fiber_); - active_fiber_ = nullptr; + // FIXME: test for main-fiber } void @@ -78,24 +75,28 @@ fiber_manager::resume_( fiber_context * f) { f->set_running(); // fiber next-to-run is same as current active-fiber // this might happen in context of this_fiber::yield() - if ( f == active_fiber_) { + if ( f == fiber_context::active() ) { return; } + // pass new fiber the fiber_manager of the current active fiber + // this might be necessary if the new fiber was miggrated from + // another thread + f->manager( fiber_context::active()->manager() ); // assign new fiber to active-fiber - std::swap( active_fiber_, f); + fiber_context * old( fiber_context::active( f) ); // push terminated fibers to terminated-queue - if ( f->is_terminated() ) { - tqueue_.push( f); + if ( old->is_terminated() ) { + tqueue_.push( old); } // resume active-fiber == start or yield to - active_fiber_->resume(); + fiber_context::active()->resume(); } void fiber_manager::spawn( fiber_context * f) { BOOST_ASSERT( nullptr != f); BOOST_ASSERT( f->is_ready() ); - BOOST_ASSERT( f != active_fiber_); + BOOST_ASSERT( f != fiber_context::active() ); // add new fiber to the scheduler sched_algo_->awakened( f); } @@ -103,19 +104,19 @@ fiber_manager::spawn( fiber_context * f) { void fiber_manager::run() { for (;;) { + // destroy terminated fibers from terminated-queue + tqueue_.clear(); // move all fibers which are ready (state_ready) // from waiting-queue to the runnable-queue - wqueue_.move_to( sched_algo_); + wqueue_.move_to( sched_algo_.get() ); // pop new fiber from ready-queue fiber_context * f( sched_algo_->pick_next() ); if ( f) { BOOST_ASSERT_MSG( f->is_ready(), "fiber with invalid state in ready-queue"); - // destroy terminated fibers from terminated-queue - tqueue_.clear(); + // set fiber_manager + f->manager( this); // resume fiber f resume_( f); - // destroy terminated fibers from terminated-queue - tqueue_.clear(); return; } else { // no fibers ready to run; the thread should sleep @@ -136,14 +137,14 @@ fiber_manager::wait( detail::spinlock_lock & lk) { bool fiber_manager::wait_until_( std::chrono::steady_clock::time_point const& timeout_time, detail::spinlock_lock & lk) { - BOOST_ASSERT( active_fiber_->is_running() ); + BOOST_ASSERT( fiber_context::active()->is_running() ); // set active-fiber to state_waiting - active_fiber_->set_waiting(); + fiber_context::active()->set_waiting(); // release lock lk.unlock(); // push active-fiber to waiting-queue - active_fiber_->time_point( timeout_time); - wqueue_.push( active_fiber_); + fiber_context::active()->time_point( timeout_time); + wqueue_.push( fiber_context::active() ); // switch to another fiber run(); // fiber has been resumed @@ -155,11 +156,11 @@ fiber_manager::wait_until_( std::chrono::steady_clock::time_point const& timeout void fiber_manager::yield() { - BOOST_ASSERT( active_fiber_->is_running() ); + BOOST_ASSERT( fiber_context::active()->is_running() ); // set active-fiber to state_waiting - active_fiber_->set_ready(); + fiber_context::active()->set_ready(); // push active-fiber to wqueue_ - wqueue_.push( active_fiber_); + wqueue_.push( fiber_context::active() ); // switch to another fiber run(); // fiber has been resumed @@ -170,17 +171,17 @@ fiber_manager::yield() { void fiber_manager::join( fiber_context * f) { BOOST_ASSERT( nullptr != f); - BOOST_ASSERT( f != active_fiber_); + BOOST_ASSERT( f != fiber_context::active() ); // set active-fiber to state_waiting - active_fiber_->set_waiting(); + fiber_context::active()->set_waiting(); // push active-fiber to waiting-queue - wqueue_.push( active_fiber_); + wqueue_.push( fiber_context::active() ); // add active-fiber to joinig-list of f - if ( ! f->join( active_fiber_) ) { + if ( ! f->join( fiber_context::active() ) ) { // f must be already terminated therefore we set // active-fiber to state_ready // FIXME: better state_running and no suspend - active_fiber_->set_ready(); + fiber_context::active()->set_ready(); } // switch to another fiber run(); @@ -191,11 +192,6 @@ fiber_manager::join( fiber_context * f) { BOOST_ASSERT( f->is_terminated() ); } -fiber_context * -fiber_manager::active() noexcept { - return active_fiber_; -} - void fiber_manager::set_sched_algo( std::unique_ptr< sched_algorithm > algo) { sched_algo_ = std::move( algo); diff --git a/src/interruption.cpp b/src/interruption.cpp index 8d303701..d8b7c76b 100644 --- a/src/interruption.cpp +++ b/src/interruption.cpp @@ -20,45 +20,45 @@ namespace boost { namespace this_fiber { disable_interruption::disable_interruption() noexcept : - set_( ( fibers::detail::scheduler::instance()->active()->interruption_blocked() ) ) { + set_( ( fibers::fiber_context::active()->interruption_blocked() ) ) { if ( ! set_) { - fibers::detail::scheduler::instance()->active()->interruption_blocked( true); + fibers::fiber_context::active()->interruption_blocked( true); } } disable_interruption::~disable_interruption() noexcept { if ( ! set_) { - fibers::detail::scheduler::instance()->active()->interruption_blocked( false); + fibers::fiber_context::active()->interruption_blocked( false); } } restore_interruption::restore_interruption( disable_interruption & disabler) noexcept : disabler_( disabler) { if ( ! disabler_.set_) { - fibers::detail::scheduler::instance()->active()->interruption_blocked( false); + fibers::fiber_context::active()->interruption_blocked( false); } } restore_interruption::~restore_interruption() noexcept { if ( ! disabler_.set_) { - fibers::detail::scheduler::instance()->active()->interruption_blocked( true); + fibers::fiber_context::active()->interruption_blocked( true); } } BOOST_FIBERS_DECL bool interruption_enabled() noexcept { - return ! fibers::detail::scheduler::instance()->active()->interruption_blocked(); + return ! fibers::fiber_context::active()->interruption_blocked(); } BOOST_FIBERS_DECL bool interruption_requested() noexcept { - return fibers::detail::scheduler::instance()->active()->interruption_requested(); + return fibers::fiber_context::active()->interruption_requested(); } BOOST_FIBERS_DECL void interruption_point() { if ( interruption_requested() && interruption_enabled() ) { - fibers::detail::scheduler::instance()->active()->request_interruption( false); + fibers::fiber_context::active()->request_interruption( false); throw fibers::fiber_interrupted(); } } diff --git a/src/mutex.cpp b/src/mutex.cpp index 4fe49937..56bddd12 100644 --- a/src/mutex.cpp +++ b/src/mutex.cpp @@ -47,7 +47,7 @@ mutex::~mutex() { void mutex::lock() { - fiber_context * f( detail::scheduler::instance()->active() ); + fiber_context * f( fiber_context::active() ); BOOST_ASSERT( nullptr != f); for (;;) { detail::spinlock_lock lk( splk_); @@ -61,7 +61,7 @@ mutex::lock() { waiting_.push_back( f); // suspend this fiber - detail::scheduler::instance()->wait( lk); + fiber_context::active()->do_wait( lk); } } diff --git a/src/recursive_mutex.cpp b/src/recursive_mutex.cpp index 67243d32..06241dad 100644 --- a/src/recursive_mutex.cpp +++ b/src/recursive_mutex.cpp @@ -53,7 +53,7 @@ recursive_mutex::~recursive_mutex() { void recursive_mutex::lock() { - fiber_context * f( detail::scheduler::instance()->active() ); + fiber_context * f( fiber_context::active() ); BOOST_ASSERT( nullptr != f); for (;;) { detail::spinlock_lock lk( splk_); @@ -67,7 +67,7 @@ recursive_mutex::lock() { waiting_.push_back( f); // suspend this fiber - detail::scheduler::instance()->wait( lk); + fiber_context::active()->do_wait( lk); } } diff --git a/src/recursive_timed_mutex.cpp b/src/recursive_timed_mutex.cpp index 101e0c5f..ac7594c0 100644 --- a/src/recursive_timed_mutex.cpp +++ b/src/recursive_timed_mutex.cpp @@ -53,7 +53,7 @@ recursive_timed_mutex::~recursive_timed_mutex() { void recursive_timed_mutex::lock() { - fiber_context * f( detail::scheduler::instance()->active() ); + fiber_context * f( fiber_context::active() ); BOOST_ASSERT( nullptr != f); for (;;) { detail::spinlock_lock lk( splk_); @@ -67,7 +67,7 @@ recursive_timed_mutex::lock() { waiting_.push_back( f); // suspend this fiber - detail::scheduler::instance()->wait( lk); + fiber_context::active()->do_wait( lk); } } @@ -88,7 +88,7 @@ recursive_timed_mutex::try_lock() { bool recursive_timed_mutex::try_lock_until_( std::chrono::steady_clock::time_point const& timeout_time) { - fiber_context * f( detail::scheduler::instance()->active() ); + fiber_context * f( fiber_context::active() ); BOOST_ASSERT( nullptr != f); for (;;) { detail::spinlock_lock lk( splk_); @@ -106,7 +106,7 @@ recursive_timed_mutex::try_lock_until_( std::chrono::steady_clock::time_point co waiting_.push_back( f); // suspend this fiber until notified or timed-out - if ( ! detail::scheduler::instance()->wait_until( timeout_time, lk) ) { + if ( ! fiber_context::active()->do_wait_until( timeout_time, lk) ) { lk.lock(); std::deque< fiber_context * >::iterator i( std::find( waiting_.begin(), waiting_.end(), f) ); if ( waiting_.end() != i) { diff --git a/src/timed_mutex.cpp b/src/timed_mutex.cpp index 274ea2f9..9ab1cb8d 100644 --- a/src/timed_mutex.cpp +++ b/src/timed_mutex.cpp @@ -47,7 +47,7 @@ timed_mutex::~timed_mutex() { void timed_mutex::lock() { - fiber_context * f( detail::scheduler::instance()->active() ); + fiber_context * f( fiber_context::active() ); BOOST_ASSERT( nullptr != f); for (;;) { detail::spinlock_lock lk( splk_); @@ -61,7 +61,7 @@ timed_mutex::lock() { waiting_.push_back( f); // suspend this fiber - detail::scheduler::instance()->wait( lk); + fiber_context::active()->do_wait( lk); } } @@ -82,7 +82,7 @@ timed_mutex::try_lock() { bool timed_mutex::try_lock_until_( std::chrono::steady_clock::time_point const& timeout_time) { - fiber_context * f( detail::scheduler::instance()->active() ); + fiber_context * f( fiber_context::active() ); BOOST_ASSERT( nullptr != f); for (;;) { detail::spinlock_lock lk( splk_); @@ -100,7 +100,7 @@ timed_mutex::try_lock_until_( std::chrono::steady_clock::time_point const& timeo waiting_.push_back( f); // suspend this fiber until notified or timed-out - if ( ! detail::scheduler::instance()->wait_until( timeout_time, lk) ) { + if ( ! fiber_context::active()->do_wait_until( timeout_time, lk) ) { lk.lock(); std::deque< fiber_context * >::iterator i( std::find( waiting_.begin(), waiting_.end(), f) ); if ( waiting_.end() != i) {