diff --git a/include/boost/fiber/algorithm.hpp b/include/boost/fiber/algorithm.hpp index 5ae4dcfb..3aa56001 100644 --- a/include/boost/fiber/algorithm.hpp +++ b/include/boost/fiber/algorithm.hpp @@ -29,6 +29,8 @@ namespace fibers { struct BOOST_FIBERS_DECL algorithm : private noncopyable { + virtual void add( detail::fiber_base::ptr_t const&) = 0; + virtual void priority( detail::fiber_base::ptr_t const&, int) = 0; virtual void join( detail::fiber_base::ptr_t const&) = 0; @@ -41,10 +43,6 @@ struct BOOST_FIBERS_DECL algorithm : private noncopyable virtual void yield() = 0; - virtual void migrate_to( fiber const&) = 0; - - virtual fiber steel_from() = 0; - virtual ~algorithm() {} }; diff --git a/include/boost/fiber/fiber.hpp b/include/boost/fiber/fiber.hpp index 4be7861c..5a85d93f 100644 --- a/include/boost/fiber/fiber.hpp +++ b/include/boost/fiber/fiber.hpp @@ -53,7 +53,7 @@ private: typedef base_t::ptr_t ptr_t; typedef void ( dummy::*safe_bool)(); - static void spawn_( fiber &); + static void spawn_( detail::fiber_base::ptr_t const&); ptr_t impl_; @@ -66,7 +66,7 @@ public: impl_() {} - fiber( ptr_t const& impl) BOOST_NOEXCEPT : + explicit fiber( ptr_t const& impl) BOOST_NOEXCEPT : impl_( impl) {} @@ -86,7 +86,7 @@ public: impl_ = ptr_t( // placement new ::new( a.allocate( 1) ) object_t( forward< fiber_fn >( fn), attr, stack_alloc, a) ); - spawn_( * this); + spawn_( impl_); } template< typename StackAllocator > @@ -102,7 +102,7 @@ public: impl_ = ptr_t( // placement new ::new( a.allocate( 1) ) object_t( forward< fiber_fn >( fn), attr, stack_alloc, a) ); - spawn_( * this); + spawn_( impl_); } template< typename StackAllocator, typename Allocator > @@ -118,7 +118,7 @@ public: impl_ = ptr_t( // placement new ::new( a.allocate( 1) ) object_t( forward< fiber_fn >( fn), attr, stack_alloc, a) ); - spawn_( * this); + spawn_( impl_); } #endif template< typename Fn > @@ -138,7 +138,7 @@ public: impl_ = ptr_t( // placement new ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); - spawn_( * this); + spawn_( impl_); } template< typename Fn, typename StackAllocator > @@ -158,7 +158,7 @@ public: impl_ = ptr_t( // placement new ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); - spawn_( * this); + spawn_( impl_); } template< typename Fn, typename StackAllocator, typename Allocator > explicit fiber( BOOST_RV_REF( Fn) fn, attributes const& attr, @@ -177,7 +177,7 @@ public: impl_ = ptr_t( // placement new ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); - spawn_( * this); + spawn_( impl_); } #else template< typename Fn > @@ -197,7 +197,7 @@ public: impl_ = ptr_t( // placement new ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); - spawn_( * this); + spawn_( impl_); } template< typename Fn, typename StackAllocator > @@ -217,7 +217,7 @@ public: impl_ = ptr_t( // placement new ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); - spawn_( * this); + spawn_( impl_); } template< typename Fn, typename StackAllocator, typename Allocator > @@ -237,7 +237,7 @@ public: impl_ = ptr_t( // placement new ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); - spawn_( * this); + spawn_( impl_); } template< typename Fn > @@ -257,7 +257,7 @@ public: impl_ = ptr_t( // placement new ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); - spawn_( * this); + spawn_( impl_); } template< typename Fn, typename StackAllocator > @@ -277,7 +277,7 @@ public: impl_ = ptr_t( // placement new ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); - spawn_( * this); + spawn_( impl_); } template< typename Fn, typename StackAllocator, typename Allocator > @@ -297,7 +297,7 @@ public: impl_ = ptr_t( // placement new ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); - spawn_( * this); + spawn_( impl_); } #endif @@ -317,19 +317,13 @@ public: } operator safe_bool() const BOOST_NOEXCEPT - { return ( ! empty() && ! impl_->is_terminated() ) ? & dummy::nonnull : 0; } + { return joinable() ? & dummy::nonnull : 0; } bool operator!() const BOOST_NOEXCEPT - { return empty() || impl_->is_terminated(); } - - void swap( fiber & other) BOOST_NOEXCEPT - { impl_.swap( other.impl_); } - - bool empty() const BOOST_NOEXCEPT - { return 0 == impl_.get(); } + { return ! joinable(); } bool joinable() const BOOST_NOEXCEPT - { return ! empty(); } + { return impl_ && ! impl_->is_terminated(); } id get_id() const BOOST_NOEXCEPT { return impl_ ? impl_->get_id() : id(); } @@ -344,6 +338,9 @@ public: void join(); void interrupt() BOOST_NOEXCEPT; + + void swap( fiber & other) BOOST_NOEXCEPT + { impl_.swap( other.impl_); } }; inline diff --git a/include/boost/fiber/round_robin.hpp b/include/boost/fiber/round_robin.hpp index f1588146..2718cec6 100644 --- a/include/boost/fiber/round_robin.hpp +++ b/include/boost/fiber/round_robin.hpp @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -49,6 +50,8 @@ public: ~round_robin() BOOST_NOEXCEPT; + void add( detail::fiber_base::ptr_t const&); + void priority( detail::fiber_base::ptr_t const&, int); void join( detail::fiber_base::ptr_t const&); @@ -62,7 +65,7 @@ public: void yield(); - void migrate_to( fiber const&); + void migrate_to( BOOST_RV_REF( fiber) f); fiber steel_from(); }; diff --git a/src/fiber.cpp b/src/fiber.cpp index 59a0cf48..9fe0a09a 100644 --- a/src/fiber.cpp +++ b/src/fiber.cpp @@ -25,8 +25,8 @@ namespace boost { namespace fibers { void -fiber::spawn_( fiber & f) -{ detail::scheduler::instance().migrate_to( f); } +fiber::spawn_( detail::fiber_base::ptr_t const& f) +{ detail::scheduler::instance().add( f); } int fiber::priority() const diff --git a/src/mutex.cpp b/src/mutex.cpp index 98cdbb9f..0c3a770b 100644 --- a/src/mutex.cpp +++ b/src/mutex.cpp @@ -34,7 +34,7 @@ mutex::lock() { while ( LOCKED == state_.exchange( LOCKED, memory_order_seq_cst) ) { - BOOST_ASSERT( this_fiber::is_fiberized() ); + if ( ! this_fiber::is_fiberized() ) ::abort(); unique_lock< detail::spinlock > lk( waiting_mtx_); waiting_.push_back( diff --git a/src/round_robin.cpp b/src/round_robin.cpp index 7a36f417..a2fdbbbc 100644 --- a/src/round_robin.cpp +++ b/src/round_robin.cpp @@ -54,6 +54,16 @@ round_robin::~round_robin() #endif } +void +round_robin::add( detail::fiber_base::ptr_t const& f) +{ + BOOST_ASSERT( f); + BOOST_ASSERT( ! f->is_running() ); + BOOST_ASSERT( ! f->is_terminated() ); + + wqueue_.push_back( f); +} + bool round_robin::run() { @@ -218,14 +228,9 @@ round_robin::priority( detail::fiber_base::ptr_t const& f, int prio) } void -round_robin::migrate_to( fiber const& f_) +round_robin::migrate_to( BOOST_RV_REF( fiber) f) { - detail::fiber_base::ptr_t f = detail::scheduler::extract( f_); - BOOST_ASSERT( f); - BOOST_ASSERT( ! f->is_running() ); - BOOST_ASSERT( ! f->is_terminated() ); - - wqueue_.push_back( f); + add( detail::scheduler::extract( f) ); } fiber diff --git a/test/test_fiber_steeling.cpp b/test/test_fiber_steeling.cpp index a07d2d40..af9e055c 100644 --- a/test/test_fiber_steeling.cpp +++ b/test/test_fiber_steeling.cpp @@ -89,10 +89,10 @@ void fn_steel_fibers( boost::fibers::round_robin * other_ds, boost::barrier * b, if ( f) { ++( * count); - ds.migrate_to( f); + ds.migrate_to( boost::move( f) ); while ( boost::fibers::run() ); } - f.detach(); + BOOST_ASSERT( ! f); } }