From ba010422f12da758767ebe851fd9bd31e698938f Mon Sep 17 00:00:00 2001 From: Oliver Kowalke Date: Thu, 20 Mar 2014 18:14:46 +0100 Subject: [PATCH] allocate worker_fiber on fiber's stack --- include/boost/fiber/detail/setup.hpp | 79 +++++++++ include/boost/fiber/detail/trampoline.hpp | 92 ++++++++++ include/boost/fiber/detail/worker_fiber.hpp | 47 +++-- include/boost/fiber/detail/worker_object.hpp | 130 -------------- include/boost/fiber/fiber.hpp | 175 ++++++------------- performance/fiber/overhead_empty.cpp | 4 +- performance/fiber/overhead_future.cpp | 2 +- performance/fiber/overhead_yield.cpp | 4 +- src/detail/worker_fiber.cpp | 44 +---- src/fiber.cpp | 7 +- 10 files changed, 271 insertions(+), 313 deletions(-) create mode 100644 include/boost/fiber/detail/setup.hpp create mode 100644 include/boost/fiber/detail/trampoline.hpp delete mode 100644 include/boost/fiber/detail/worker_object.hpp diff --git a/include/boost/fiber/detail/setup.hpp b/include/boost/fiber/detail/setup.hpp new file mode 100644 index 00000000..a3ec5850 --- /dev/null +++ b/include/boost/fiber/detail/setup.hpp @@ -0,0 +1,79 @@ + +// Copyright Oliver Kowalke 2009. +// 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_SETUP_H +#define BOOST_FIBERS_DETAIL_SETUP_H + +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef BOOST_HAS_ABI_HEADERS +# include BOOST_ABI_PREFIX +#endif + +namespace boost { +namespace fibers { +namespace detail { + +template< typename Fn > +struct setup +{ + typedef typename worker_fiber::coro_t coro_t; + + struct dummy {}; + + Fn fn; + typename coro_t::call_type * caller; + worker_fiber * f; + +#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES + setup( Fn fn_, + coro_t::call_type * caller_) : + fn( forward< Fn >( fn_) ), + caller( caller_), + f( 0) + { BOOST_ASSERT( 0 != caller); } +#endif + setup( BOOST_RV_REF( Fn) fn_, + coro_t::call_type * caller_, + typename disable_if< + is_same< typename decay< Fn >::type, setup >, + dummy* + >::type = 0) : +#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES + fn( fn_), +#else + fn( forward< Fn >( fn_) ), +#endif + caller( caller_), + f( 0) + { BOOST_ASSERT( 0 != caller); } + + worker_fiber * allocate() + { + // enter fiber-fn (trampoline<>) + // and pas this as argument + ( * caller)( this); + // jumped back; move coroutine to worker_fiber + f->caller_ = boost::move( * caller); + return f; + } +}; + +}}} + +#ifdef BOOST_HAS_ABI_HEADERS +# include BOOST_ABI_SUFFIX +#endif + +#endif // BOOST_FIBERS_DETAIL_SETUP_H diff --git a/include/boost/fiber/detail/trampoline.hpp b/include/boost/fiber/detail/trampoline.hpp new file mode 100644 index 00000000..6bdb5504 --- /dev/null +++ b/include/boost/fiber/detail/trampoline.hpp @@ -0,0 +1,92 @@ + +// Copyright Oliver Kowalke 2009. +// 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_TRAMPOLINE_H +#define BOOST_FIBERS_DETAIL_TRAMPOLINE_H + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef BOOST_HAS_ABI_HEADERS +# include BOOST_ABI_PREFIX +#endif + +namespace boost { +namespace fibers { +namespace detail { + +namespace coro = boost::coroutines; + +template< typename Fn > +void trampoline( typename worker_fiber::coro_t::yield_type & yield) +{ + BOOST_ASSERT( yield); + + void * p( yield.get() ); + BOOST_ASSERT( p); + setup< Fn > * from( static_cast< setup< Fn > * >( p) ); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + Fn fn_( forward< Fn >( from->fn) ); +#else + Fn fn_( move( from->fn) ); +#endif + + worker_fiber f( & yield); + from->f = & f; + + f.set_running(); + f.suspend(); + + try + { +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + Fn fn( forward< Fn >( fn_) ); +#else + Fn fn( move( fn_) ); +#endif + BOOST_ASSERT( f.is_running() ); + fn(); + BOOST_ASSERT( f.is_running() ); + } + catch ( coro::detail::forced_unwind const&) + { + f.set_terminated(); + f.release(); + throw; + } + catch ( fiber_interrupted const&) + { f.set_exception( current_exception() ); } + catch (...) + { std::terminate(); } + + f.set_terminated(); + f.release(); + f.suspend(); + + BOOST_ASSERT_MSG( false, "fiber already terminated"); +} + +}}} + +#ifdef BOOST_HAS_ABI_HEADERS +# include BOOST_ABI_SUFFIX +#endif + +#endif // BOOST_FIBERS_DETAIL_TRAMPOLINE_H diff --git a/include/boost/fiber/detail/worker_fiber.hpp b/include/boost/fiber/detail/worker_fiber.hpp index 65848eb6..c785b97c 100644 --- a/include/boost/fiber/detail/worker_fiber.hpp +++ b/include/boost/fiber/detail/worker_fiber.hpp @@ -46,7 +46,15 @@ namespace coro = boost::coroutines; class BOOST_FIBERS_DECL worker_fiber : public fiber_base { +public: + typedef coro::symmetric_coroutine< + void * + > coro_t; + private: + template< typename Fn > + friend struct setup; + enum state_t { READY = 0, @@ -75,17 +83,12 @@ private: }; typedef std::map< uintptr_t, fss_data > fss_data_t; - typedef coro::symmetric_coroutine< - void - > coro_t; - fss_data_t fss_data_; - worker_fiber * nxt_; - clock_type::time_point tp_; + static void * null_ptr; - void trampoline_( coro_t::yield_type &); - -protected: + fss_data_t fss_data_; + worker_fiber * nxt_; + clock_type::time_point tp_; coro_t::yield_type * callee_; coro_t::call_type caller_; atomic< state_t > state_; @@ -95,14 +98,10 @@ protected: spinlock splk_; std::vector< worker_fiber * > waiting_; - void release(); - - virtual void run() = 0; - public: - worker_fiber( attributes const&); + worker_fiber( coro_t::yield_type *); - virtual ~worker_fiber(); + ~worker_fiber(); id get_id() const BOOST_NOEXCEPT { return id( const_cast< worker_fiber * >( this) ); } @@ -180,9 +179,12 @@ public: void * data, bool cleanup_existing); - exception_ptr exception() const BOOST_NOEXCEPT + exception_ptr get_exception() const BOOST_NOEXCEPT { return except_; } + void set_exception( exception_ptr except) BOOST_NOEXCEPT + { except_ = except; } + void resume( worker_fiber * f) { if ( 0 == f) @@ -191,7 +193,7 @@ public: BOOST_ASSERT( is_running() ); // set by the scheduler-algorithm // called from main-fiber - caller_(); + caller_( null_ptr); } else { @@ -200,7 +202,7 @@ public: BOOST_ASSERT( is_running() ); // set by the scheduler-algorithm BOOST_ASSERT( f->callee_); - ( * f->callee_)( caller_); + ( * f->callee_)( caller_, null_ptr); } } @@ -232,7 +234,14 @@ public: void time_point_reset() { tp_ = (clock_type::time_point::max)(); } - virtual void deallocate() = 0; + void deallocate() + { + //this->~worker_fiber(); + callee_ = 0; + coro_t::call_type tmp( move( caller_) ); + } + + void release(); }; }}} diff --git a/include/boost/fiber/detail/worker_object.hpp b/include/boost/fiber/detail/worker_object.hpp deleted file mode 100644 index 888f833b..00000000 --- a/include/boost/fiber/detail/worker_object.hpp +++ /dev/null @@ -1,130 +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_WORKER_OBJECT_H -#define BOOST_FIBERS_DETAIL_WORKER_OBJECT_H - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -# if defined(BOOST_MSVC) -# pragma warning(push) -# pragma warning(disable:4355) -# endif - -namespace boost { -namespace fibers { -namespace detail { - -template< typename Fn, typename Allocator > -class worker_object : public worker_fiber -{ -public: - typedef typename Allocator::template rebind< - worker_object< Fn, Allocator > - >::other allocator_t; - -#ifndef BOOST_NO_RVALUE_REFERENCES - worker_object( Fn && fn, attributes const& attrs, - allocator_t const& alloc) : - base_t( attrs), - fn_( forward< Fn >( fn) ), - alloc_( alloc) - { - BOOST_ASSERT( caller_); - BOOST_ASSERT( 0 == callee_); - - caller_(); // jump to trampoline - - BOOST_ASSERT( 0 != callee_); - BOOST_ASSERT( * callee_); - - set_ready(); // fiber is setup and now ready to run - } -#else - worker_object( Fn fn, attributes const& attrs, - allocator_t const& alloc) : - base_t( attrs), - fn_( fn), - alloc_( alloc) - { - BOOST_ASSERT( caller_); - BOOST_ASSERT( 0 == callee_); - - caller_(); // jump to trampoline - - BOOST_ASSERT( 0 != callee_); - BOOST_ASSERT( * callee_); - - set_ready(); // fiber is setup and now ready to run - } - - worker_object( BOOST_RV_REF( Fn) fn, attributes const& attrs, - allocator_t const& alloc) : - base_t( attrs), - fn_( fn), - alloc_( alloc) - { - BOOST_ASSERT( caller_); - BOOST_ASSERT( 0 == callee_); - - caller_(); // jump to trampoline - - BOOST_ASSERT( 0 != callee_); - BOOST_ASSERT( * callee_); - - set_ready(); // fiber is setup and now ready to run - } -#endif - - void deallocate() - { destroy_( alloc_, this); } - -private: - typedef worker_fiber base_t; - - Fn fn_; - allocator_t alloc_; - - static void destroy_( allocator_t & alloc, worker_object * p) - { - alloc.destroy( p); - alloc.deallocate( p, 1); - } - - worker_object( worker_object &); - worker_object & operator=( worker_object const&); - - void run() - { fn_(); } -}; - -}}} - -# if defined(BOOST_MSVC) -# pragma warning(pop) -# endif - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -#endif // BOOST_FIBERS_DETAIL_WORKER_OBJECT_H diff --git a/include/boost/fiber/fiber.hpp b/include/boost/fiber/fiber.hpp index 2f862228..40b95e8c 100644 --- a/include/boost/fiber/fiber.hpp +++ b/include/boost/fiber/fiber.hpp @@ -14,14 +14,16 @@ #include #include +#include #include #include #include #include #include +#include +#include #include -#include #include #ifdef BOOST_HAS_ABI_HEADERS @@ -50,6 +52,7 @@ private: friend class detail::scheduler; typedef detail::worker_fiber base_t; + typedef base_t::coro_t coro_t; detail::worker_fiber * impl_; @@ -68,170 +71,106 @@ public: #ifdef BOOST_MSVC typedef void ( * fiber_fn)(); - explicit fiber( fiber_fn fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = stack_allocator(), - std::allocator< fiber > const& alloc = std::allocator< fiber >() ) : + explicit fiber( fiber_fn fn, attributes const& attrs = attributes(), + stack_allocator const& stack_alloc = stack_allocator() ) : impl_( 0) { - typedef detail::worker_object< - fiber_fn, std::allocator< fiber > - > object_t; - object_t::allocator_t a( alloc); - impl_ = ::new( a.allocate( 1) ) object_t( forward< fiber_fn >( fn), attr, a); + typename coro_t::call_type coro( detail::trampoline< fiber_fn >, attrs, stack_alloc); + detail::setup< fiber_fn > s( forward< fiber_fn >( fn), & coro); + impl_ = s.allocate(); + BOOST_ASSERT( 0 != impl_); + start_fiber_(); } template< typename StackAllocator > - explicit fiber( fiber_fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< fiber > const& alloc = std::allocator< fiber >() ) : + explicit fiber( fiber_fn fn, attributes const& attrs, + StackAllocator const& stack_alloc) : impl_( 0) { - typedef detail::worker_object< - fiber_fn, std::allocator< fiber > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ::new( a.allocate( 1) ) object_t( forward< fiber_fn >( fn), attr, a); - start_fiber_(); - } + typename coro_t::call_type coro( detail::trampoline< fiber_fn >, attrs, stack_alloc); + detail::setup< fiber_fn > s( forward< fiber_fn >( fn), & coro); + impl_ = s.allocate(); + BOOST_ASSERT( 0 != impl_); - template< typename StackAllocator, typename Allocator > - explicit fiber( fiber_fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc) : - impl_( 0) - { - typedef detail::worker_object< - fiber_fn, Allocator - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ::new( a.allocate( 1) ) object_t( forward< fiber_fn >( fn), attr, a); start_fiber_(); } #endif template< typename Fn > - explicit fiber( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = stack_allocator(), - std::allocator< fiber > const& alloc = std::allocator< fiber >() ) : + explicit fiber( BOOST_RV_REF( Fn) fn, attributes const& attrs = attributes(), + stack_allocator const& stack_alloc = stack_allocator() ) : impl_( 0) { - typedef detail::worker_object< - Fn, std::allocator< fiber > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, a); + typename coro_t::call_type coro( detail::trampoline< Fn >, attrs, stack_alloc); + detail::setup< Fn > s( forward< Fn >( fn), & coro); + impl_ = s.allocate(); + BOOST_ASSERT( 0 != impl_); + start_fiber_(); } template< typename Fn, typename StackAllocator > - explicit fiber( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< fiber > const& alloc = std::allocator< fiber >() ) : + explicit fiber( BOOST_RV_REF( Fn) fn, attributes const& attrs, + StackAllocator const& stack_alloc) : impl_( 0) { - typedef detail::worker_object< - Fn, std::allocator< fiber > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, a); - start_fiber_(); - } + typename coro_t::call_type coro( detail::trampoline< Fn >, attrs, stack_alloc); + detail::setup< Fn > s( forward< Fn >( fn), & coro); + impl_ = s.allocate(); + BOOST_ASSERT( 0 != impl_); - template< typename Fn, typename StackAllocator, typename Allocator > - explicit fiber( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc) : - impl_( 0) - { - typedef detail::worker_object< - Fn, Allocator - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, a); start_fiber_(); } #else template< typename Fn > - explicit fiber( Fn fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = stack_allocator(), - std::allocator< fiber > const& alloc = std::allocator< fiber >() ) : + explicit fiber( Fn fn, attributes const& attrs = attributes(), + stack_allocator const& stack_alloc = stack_allocator() ) : impl_( 0) { - typedef detail::worker_object< - Fn, std::allocator< fiber > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ::new( a.allocate( 1) ) object_t( fn, attr, a); + typename coro_t::call_type coro( detail::trampoline< Fn >, attrs, stack_alloc); + detail::setup< Fn > s( fn, & coro); + impl_ = s.allocate(); + BOOST_ASSERT( 0 != impl_); + start_fiber_(); } template< typename Fn, typename StackAllocator > - explicit fiber( Fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< fiber > const& alloc = std::allocator< fiber >() ) : + explicit fiber( Fn fn, attributes const& attrs, + StackAllocator const& stack_alloc) : impl_( 0) { - typedef detail::worker_object< - Fn, std::allocator< fiber > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ::new( a.allocate( 1) ) object_t( fn, attr, a); - start_fiber_(); - } + typename coro_t::call_type coro( detail::trampoline< Fn >, attrs, stack_alloc); + detail::setup< Fn > s( fn, & coro); + impl_ = s.allocate(); + BOOST_ASSERT( 0 != impl_); - template< typename Fn, typename StackAllocator, typename Allocator > - explicit fiber( Fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc) : - impl_( 0) - { - typedef detail::worker_object< - Fn, Allocator - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ::new( a.allocate( 1) ) object_t( fn, attr, a); start_fiber_(); } template< typename Fn > - explicit fiber( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = stack_allocator(), - std::allocator< fiber > const& alloc = std::allocator< fiber >() ) : + explicit fiber( BOOST_RV_REF( Fn) fn, attributes const& attrs = attributes(), + stack_allocator const& stack_alloc = stack_allocator() ) : impl_( 0) { - typedef detail::worker_object< - Fn, std::allocator< fiber > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ::new( a.allocate( 1) ) object_t( fn, attr, a); + typename coro_t::call_type coro( detail::trampoline< Fn >, attrs, stack_alloc); + detail::setup< Fn > s( fn, & coro); + impl_ = s.allocate(); + BOOST_ASSERT( 0 != impl_); + start_fiber_(); } template< typename Fn, typename StackAllocator > - explicit fiber( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< fiber > const& alloc = std::allocator< fiber >() ) : + explicit fiber( BOOST_RV_REF( Fn) fn, attributes const& attrs, + StackAllocator const& stack_alloc) : impl_( 0) { - typedef detail::worker_object< - Fn, std::allocator< fiber > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ::new( a.allocate( 1) ) object_t( fn, attr, a); - start_fiber_(); - } + typename coro_t::call_type coro( detail::trampoline< Fn >, attrs, stack_alloc); + detail::setup< Fn > s( fn, & coro); + impl_ = s.allocate(); + BOOST_ASSERT( 0 != impl_); - template< typename Fn, typename StackAllocator, typename Allocator > - explicit fiber( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc) : - impl_( 0) - { - typedef detail::worker_object< - Fn, Allocator - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ::new( a.allocate( 1) ) object_t( fn, attr, a); start_fiber_(); } #endif @@ -270,7 +209,7 @@ public: { return 0 != impl_ /* && ! impl_->is_terminated() */; } id get_id() const BOOST_NOEXCEPT - { return impl_ ? impl_->get_id() : id(); } + { return 0 != impl_ ? impl_->get_id() : id(); } int priority() const BOOST_NOEXCEPT; diff --git a/performance/fiber/overhead_empty.cpp b/performance/fiber/overhead_empty.cpp index 46e110cb..1d3cb17a 100644 --- a/performance/fiber/overhead_empty.cpp +++ b/performance/fiber/overhead_empty.cpp @@ -29,11 +29,11 @@ template< typename StackAllocator > duration_type measure( duration_type overhead, StackAllocator const& stack_alloc) { boost::fibers::attributes attrs( unwind_stack, preserve_fpu); - boost::fibers::fiber( worker, attrs, stack_alloc).join(); + boost::fibers::fiber( worker, attrs).join(); time_point_type start( clock_type::now() ); for ( std::size_t i = 0; i < jobs; ++i) { - boost::fibers::fiber( worker, attrs, stack_alloc).join(); + boost::fibers::fiber( worker, attrs).join(); } duration_type total = clock_type::now() - start; total -= overhead_clock(); // overhead of measurement diff --git a/performance/fiber/overhead_future.cpp b/performance/fiber/overhead_future.cpp index 94e744f5..0981f700 100644 --- a/performance/fiber/overhead_future.cpp +++ b/performance/fiber/overhead_future.cpp @@ -30,7 +30,7 @@ void test_future( boost::fibers::attributes const& attrs, StackAllocator const& { boost::fibers::packaged_task< void() > pt( worker); boost::fibers::future< void > f( pt.get_future() ); - boost::fibers::fiber( boost::move( pt), attrs, stack_alloc).detach(); + boost::fibers::fiber( boost::move( pt), attrs).detach(); f.wait(); } diff --git a/performance/fiber/overhead_yield.cpp b/performance/fiber/overhead_yield.cpp index af99238b..a036dfaf 100644 --- a/performance/fiber/overhead_yield.cpp +++ b/performance/fiber/overhead_yield.cpp @@ -30,11 +30,11 @@ template< typename StackAllocator > duration_type measure( duration_type overhead, StackAllocator const& stack_alloc) { boost::fibers::attributes attrs( unwind_stack, preserve_fpu); - boost::fibers::fiber( worker, attrs, stack_alloc).join(); + boost::fibers::fiber( worker, attrs).join(); time_point_type start( clock_type::now() ); for ( std::size_t i = 0; i < jobs; ++i) { - boost::fibers::fiber( worker, attrs, stack_alloc).join(); + boost::fibers::fiber( worker, attrs).join(); } duration_type total = clock_type::now() - start; total -= overhead_clock(); // overhead of measurement diff --git a/src/detail/worker_fiber.cpp b/src/detail/worker_fiber.cpp index 19d34bcc..9835ae0d 100644 --- a/src/detail/worker_fiber.cpp +++ b/src/detail/worker_fiber.cpp @@ -23,55 +23,21 @@ namespace boost { namespace fibers { namespace detail { -void -worker_fiber::trampoline_( coro_t::yield_type & yield) -{ - BOOST_ASSERT( yield); - BOOST_ASSERT( ! is_terminated() ); +void * worker_fiber::null_ptr = 0; - callee_ = & yield; - set_running(); - suspend(); - - try - { - BOOST_ASSERT( is_running() ); - run(); - BOOST_ASSERT( is_running() ); - } - catch ( coro::detail::forced_unwind const&) - { - set_terminated(); - release(); - throw; - } - catch ( fiber_interrupted const&) - { except_ = current_exception(); } - catch (...) - { std::terminate(); } - - set_terminated(); - release(); - suspend(); - - BOOST_ASSERT_MSG( false, "fiber already terminated"); -} - -worker_fiber::worker_fiber( attributes const& attrs) : +worker_fiber::worker_fiber( coro_t::yield_type * callee) : fiber_base(), fss_data_(), nxt_( 0), tp_( (clock_type::time_point::max)() ), - callee_( 0), - caller_( - boost::bind( & worker_fiber::trampoline_, this, _1), - attrs), + callee_( callee), + caller_(), state_( READY), flags_( 0), priority_( 0), except_(), waiting_() -{} +{ BOOST_ASSERT( callee_); } worker_fiber::~worker_fiber() { diff --git a/src/fiber.cpp b/src/fiber.cpp index 658c14dd..36649d82 100644 --- a/src/fiber.cpp +++ b/src/fiber.cpp @@ -24,7 +24,10 @@ namespace fibers { void fiber::start_fiber_() -{ detail::scheduler::instance()->spawn( impl_); } +{ + impl_->set_ready(); + detail::scheduler::instance()->spawn( impl_); +} int fiber::priority() const BOOST_NOEXCEPT @@ -80,7 +83,7 @@ fiber::join() detail::worker_fiber * tmp = 0; std::swap( tmp, impl_); // check if joined fiber was interrupted - exception_ptr except( tmp->exception() ); + exception_ptr except( tmp->get_exception() ); tmp->deallocate(); if ( except) rethrow_exception( except);