From ddbdd91cedc3a9c080cf6d733b540c6f0e28f21d Mon Sep 17 00:00:00 2001 From: Oliver Kowalke Date: Mon, 24 Nov 2014 19:58:48 +0100 Subject: [PATCH] use execution_context --- include/boost/fiber/detail/fiber_base.hpp | 11 ++- include/boost/fiber/detail/main_fiber.hpp | 4 +- include/boost/fiber/detail/worker_fiber.hpp | 62 ++++++++--------- include/boost/fiber/fiber.hpp | 75 +-------------------- src/fiber_manager.cpp | 10 ++- 5 files changed, 40 insertions(+), 122 deletions(-) diff --git a/include/boost/fiber/detail/fiber_base.hpp b/include/boost/fiber/detail/fiber_base.hpp index d2d16022..1f8f4131 100644 --- a/include/boost/fiber/detail/fiber_base.hpp +++ b/include/boost/fiber/detail/fiber_base.hpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -70,7 +71,7 @@ private: typedef std::map< uintptr_t, fss_data > fss_data_t; atomic< std::size_t > use_count_; - context::fcontext_t ctx_; + context::execution_context ctx_; fss_data_t fss_data_; chrono::high_resolution_clock::time_point tp_; atomic< state_t > state_; @@ -134,7 +135,7 @@ public: fiber_base * nxt; - fiber_base( context::fcontext_t ctx) : + fiber_base( context::execution_context ctx) : use_count_( 1), // allocated on stack ctx_( ctx), fss_data_(), @@ -230,13 +231,11 @@ public: void set_exception( exception_ptr except) BOOST_NOEXCEPT { except_ = except; } - void resume( fiber_base * current, bool preserve_fpu_) + void resume() { - BOOST_ASSERT( 0 != current); BOOST_ASSERT( is_running() ); // set by the scheduler-algorithm - context::jump_fcontext( - & current->ctx_, ctx_, reinterpret_cast< intptr_t >( this), preserve_fpu_); + ctx_.jump_to(); } chrono::high_resolution_clock::time_point const& time_point() const BOOST_NOEXCEPT diff --git a/include/boost/fiber/detail/main_fiber.hpp b/include/boost/fiber/detail/main_fiber.hpp index cb6ed440..c7aa652e 100644 --- a/include/boost/fiber/detail/main_fiber.hpp +++ b/include/boost/fiber/detail/main_fiber.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -25,7 +26,8 @@ class main_fiber : public fiber_base { public: main_fiber() : - fiber_base( 0) // main-fiber represents main-context + fiber_base( + context::execution_context::current() ) // main-fiber represents main-context { thread_affinity( true); set_running(); diff --git a/include/boost/fiber/detail/worker_fiber.hpp b/include/boost/fiber/detail/worker_fiber.hpp index 8802c158..79bafd63 100644 --- a/include/boost/fiber/detail/worker_fiber.hpp +++ b/include/boost/fiber/detail/worker_fiber.hpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -34,14 +35,9 @@ namespace boost { namespace fibers { namespace detail { -template< typename Fn, typename StackAllocator > class worker_fiber : public fiber_base { private: - Fn fn_; - StackAllocator salloc_; - stack_context sctx_; - void run_() { try @@ -67,28 +63,34 @@ private: } public: - static void entry_func( intptr_t); + template< typename StackAllocator, typename Fn > + worker_fiber( StackAllocator const& salloc, Fn && fn_) : + fiber_base( + context::execution_context( salloc, + [=,&fn_](){ + try + { + BOOST_ASSERT( is_running() ); + // store fiber-fn + Fn fn( std::forward< Fn >( fn_) ); + fn_(); + BOOST_ASSERT( is_running() ); + } + catch( fiber_interrupted const& ) + { except_ = current_exception(); } + catch( ... ) + { std::terminate(); } -#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES - worker_fiber( Fn fn, void * sp, std::size_t size, - StackAllocator const& salloc, stack_context const& sctx) : - fiber_base( context::make_fcontext( sp, size, & worker_fiber::entry_func) ), - fn_( boost::forward< Fn >( fn) ), - salloc_( salloc), - sctx_( sctx) - {} -#endif + // mark fiber as terminated + set_terminated(); + // notify waiting (joining) fibers + release(); - worker_fiber( BOOST_RV_REF( Fn) fn, void * sp, std::size_t size, - StackAllocator const& salloc, stack_context const& sctx) : - fiber_base( context::make_fcontext( sp, size, & worker_fiber::entry_func) ), -#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES - fn_( fn), -#else - fn_( boost::forward< Fn >( fn) ), -#endif - salloc_( salloc), - sctx_( sctx) + // switch to another fiber + fibers::fm_run(); + + BOOST_ASSERT_MSG( false, "fiber already terminated"); + }) {} ~worker_fiber() @@ -107,16 +109,6 @@ public: } }; -template< typename Fn, typename StackAllocator > -void -worker_fiber< Fn, StackAllocator >::entry_func( intptr_t param) -{ - worker_fiber< Fn, StackAllocator > * f( - reinterpret_cast< worker_fiber< Fn, StackAllocator > * >( param) ); - BOOST_ASSERT( 0 != f); - f->run_(); -} - }}} # if defined(BOOST_MSVC) diff --git a/include/boost/fiber/fiber.hpp b/include/boost/fiber/fiber.hpp index 0fb318c8..021428fd 100644 --- a/include/boost/fiber/fiber.hpp +++ b/include/boost/fiber/fiber.hpp @@ -131,82 +131,9 @@ public: impl_( impl) {} -#ifdef BOOST_MSVC - fiber( fiber_fn fn) : - impl_() - { - attributes attrs; - stack_allocator salloc; - impl_.reset( make_fiber_( salloc, attrs, fn) ); - start_(); - } - - fiber( attributes const& attrs, fiber_fn fn) : - impl_() - { - stack_allocator salloc; - impl_.reset( make_fiber_( salloc, attrs, fn) ); - start_(); - } - - template< typename StackAllocator > - fiber( boost::allocator_arg_t, StackAllocator salloc, fiber_fn fn) : - impl_() - { - attributes attrs; - impl_.reset( make_fiber_( salloc, attrs, fn) ); - start_(); - } - - template< typename StackAllocator > - fiber( boost::allocator_arg_t, StackAllocator salloc, attributes const& attrs, fiber_fn fn) : - impl_() - { - impl_.reset( make_fiber_( salloc, attrs, fn) ); - start_(); - } -#endif - -#ifdef BOOST_NO_RVALUE_REFERENCES - template< typename Fn > - fiber( Fn fn) : - impl_() - { - attributes attrs; - stack_allocator salloc; - impl_.reset( make_fiber_( salloc, attrs, fn) ); - start_(); - } template< typename Fn > - fiber( attributes const& attrs, Fn fn) : - impl_() - { - stack_allocator salloc; - impl_.reset( make_fiber_( salloc, attrs, fn) ); - start_(); - } - - template< typename StackAllocator, typename Fn > - fiber( boost::allocator_arg_t, StackAllocator salloc, Fn fn) : - impl_() - { - attributes attrs; - impl_.reset( make_fiber_( salloc, attrs, fn) ); - start_(); - } - - template< typename StackAllocator, typename Fn > - fiber( boost::allocator_arg_t, StackAllocator salloc, attributes const& attrs, Fn fn) : - impl_() - { - impl_.reset( make_fiber_( salloc, attrs, fn) ); - start_(); - } -#endif - - template< typename Fn > - fiber( BOOST_RV_REF( Fn) fn) : + fiber( Fn && fn) : impl_() { attributes attrs; diff --git a/src/fiber_manager.cpp b/src/fiber_manager.cpp index c7d7d598..a836288d 100644 --- a/src/fiber_manager.cpp +++ b/src/fiber_manager.cpp @@ -65,7 +65,6 @@ fiber_manager::~fiber_manager() BOOST_NOEXCEPT fm_run(); #endif active_fiber = 0; - fprintf(stderr, "~fiber_manager()\n"); } void fm_resume_( detail::fiber_base * f) @@ -79,16 +78,15 @@ void fm_resume_( detail::fiber_base * f) // set fiber to state running f->set_running(); - // fiber next-to-run is same as current fiber + // fiber next-to-run is same as current active fiber // this might happen in context of this_fiber::yield() if ( f == fm->active_fiber) return; - // store active-fiber in local var - detail::fiber_base * current = fm->active_fiber; // assign new fiber to active-fiber fm->active_fiber = f; + // resume active-fiber == start or yield to - fm->active_fiber->resume( current, fm->preserve_fpu); + fm->active_fiber->resume(); } chrono::high_resolution_clock::time_point fm_next_wakeup() @@ -144,7 +142,7 @@ void fm_run() { BOOST_ASSERT_MSG( f->is_ready(), "fiber with invalid state in ready-queue"); - // if current fiber is in state terminated, push it to terminated-queue + // if current active fiber is in state terminated, push it to terminated-queue if ( fm->active_fiber->is_terminated() ) fm->tqueue.push_back( fm->active_fiber); // resume fiber f