2
0
mirror of https://github.com/boostorg/fiber.git synced 2026-02-02 08:52:07 +00:00
This commit is contained in:
Oliver Kowalke
2013-01-27 10:14:15 +01:00
parent 007f259780
commit 0abfc511bb
10 changed files with 69 additions and 64 deletions

View File

@@ -8,6 +8,7 @@
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/move/move.hpp>
#include <boost/thread/locks.hpp>
#include <boost/utility.hpp>
@@ -29,11 +30,9 @@ namespace fibers {
struct BOOST_FIBERS_DECL algorithm : private noncopyable
{
virtual void add( detail::fiber_base::ptr_t const&) = 0;
virtual void priority( BOOST_RV_REF( fiber), int) = 0;
virtual void priority( detail::fiber_base::ptr_t const&, int) = 0;
virtual void join( detail::fiber_base::ptr_t const&) = 0;
virtual void join( BOOST_RV_REF( fiber) ) = 0;
virtual detail::fiber_base::ptr_t active() = 0;
@@ -43,6 +42,10 @@ 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() {}
};

View File

@@ -26,7 +26,7 @@
#include <boost/fiber/detail/spinlock.hpp>
#include <boost/fiber/detail/states.hpp>
#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
@@ -39,7 +39,13 @@ namespace detail {
class BOOST_FIBERS_DECL fiber_base : private noncopyable
{
public:
typedef intrusive_ptr< fiber_base > ptr_t;
struct deleter
{
void operator()( fiber_base * f)
{ f->deallocate_object(); }
};
typedef shared_ptr< fiber_base > ptr_t;
//typedef intrusive_ptr< fiber_base > ptr_t;
private:
template< typename X, typename Y, typename Z >
@@ -69,7 +75,7 @@ public:
friend class fiber_base;
fiber_base::ptr_t impl_;
public:
explicit id( fiber_base::ptr_t const& impl) BOOST_NOEXCEPT :
impl_( impl)
{}

View File

@@ -53,7 +53,7 @@ private:
typedef base_t::ptr_t ptr_t;
typedef void ( dummy::*safe_bool)();
static void spawn_( detail::fiber_base::ptr_t const&);
static void spawn_( fiber &);
ptr_t impl_;
@@ -66,7 +66,7 @@ public:
impl_()
{}
explicit fiber( ptr_t const& impl) BOOST_NOEXCEPT :
fiber( ptr_t const& impl) BOOST_NOEXCEPT :
impl_( impl)
{}
@@ -85,8 +85,8 @@ public:
object_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) object_t( forward< fiber_fn >( fn), attr, stack_alloc, a) );
spawn_( impl_);
::new( a.allocate( 1) ) object_t( forward< fiber_fn >( fn), attr, stack_alloc, a), detail::fiber_base::deleter() );
spawn_( * this);
}
template< typename StackAllocator >
@@ -101,8 +101,8 @@ public:
object_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) object_t( forward< fiber_fn >( fn), attr, stack_alloc, a) );
spawn_( impl_);
::new( a.allocate( 1) ) object_t( forward< fiber_fn >( fn), attr, stack_alloc, a), detail::fiber_base::deleter() );
spawn_( * this);
}
template< typename StackAllocator, typename Allocator >
@@ -117,8 +117,8 @@ public:
object_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) object_t( forward< fiber_fn >( fn), attr, stack_alloc, a) );
spawn_( impl_);
::new( a.allocate( 1) ) object_t( forward< fiber_fn >( fn), attr, stack_alloc, a), detail::fiber_base::deleter() );
spawn_( * this);
}
#endif
template< typename Fn >
@@ -137,8 +137,8 @@ public:
typename object_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) );
spawn_( impl_);
::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a), detail::fiber_base::deleter() );
spawn_( * this);
}
template< typename Fn, typename StackAllocator >
@@ -157,8 +157,8 @@ public:
typename object_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) );
spawn_( impl_);
::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a), detail::fiber_base::deleter() );
spawn_( * this);
}
template< typename Fn, typename StackAllocator, typename Allocator >
explicit fiber( BOOST_RV_REF( Fn) fn, attributes const& attr,
@@ -176,8 +176,8 @@ public:
typename object_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) );
spawn_( impl_);
::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a), detail::fiber_base::deleter() );
spawn_( * this);
}
#else
template< typename Fn >
@@ -196,8 +196,8 @@ public:
typename object_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) );
spawn_( impl_);
::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a), detail::fiber_base::deleter() );
spawn_( * this);
}
template< typename Fn, typename StackAllocator >
@@ -216,8 +216,8 @@ public:
typename object_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) );
spawn_( impl_);
::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a), detail::fiber_base::deleter() );
spawn_( * this);
}
template< typename Fn, typename StackAllocator, typename Allocator >
@@ -236,8 +236,8 @@ public:
typename object_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) );
spawn_( impl_);
::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a), detail::fiber_base::deleter() );
spawn_( * this);
}
template< typename Fn >
@@ -256,8 +256,8 @@ public:
typename object_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) );
spawn_( impl_);
::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a), detail::fiber_base::deleter() );
spawn_( * this);
}
template< typename Fn, typename StackAllocator >
@@ -276,8 +276,8 @@ public:
typename object_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) );
spawn_( impl_);
::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a), detail::fiber_base::deleter() );
spawn_( * this);
}
template< typename Fn, typename StackAllocator, typename Allocator >
@@ -296,8 +296,8 @@ public:
typename object_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) );
spawn_( impl_);
::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a), detail::fiber_base::deleter() );
spawn_( * this);
}
#endif
@@ -317,16 +317,23 @@ public:
}
operator safe_bool() const BOOST_NOEXCEPT
{ return joinable() ? & dummy::nonnull : 0; }
{ return ( ! empty() && ! impl_->is_terminated() ) ? & dummy::nonnull : 0; }
bool operator!() const BOOST_NOEXCEPT
{ return ! joinable(); }
{ return empty() || impl_->is_terminated(); }
void swap( fiber & other) BOOST_NOEXCEPT
{ impl_.swap( other.impl_); }
bool empty() const BOOST_NOEXCEPT
{ return 0 == impl_.get(); }
bool joinable() const BOOST_NOEXCEPT
{ return impl_ && ! impl_->is_terminated(); }
{ return ! empty(); }
id get_id() const BOOST_NOEXCEPT
{ return impl_ ? impl_->get_id() : id(); }
{ return impl_ ? id( impl_) : id(); }
//{ return impl_ ? impl_->get_id() : id(); }
int priority() const BOOST_NOEXCEPT;
@@ -338,9 +345,6 @@ public:
void join();
void interrupt() BOOST_NOEXCEPT;
void swap( fiber & other) BOOST_NOEXCEPT
{ impl_.swap( other.impl_); }
};
inline

View File

@@ -12,7 +12,6 @@
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/move/move.hpp>
#include <boost/thread/locks.hpp>
#include <boost/fiber/detail/config.hpp>
@@ -50,8 +49,6 @@ 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&);
@@ -65,7 +62,7 @@ public:
void yield();
void migrate_to( BOOST_RV_REF( fiber) f);
void migrate_to( fiber const&);
fiber steel_from();
};

View File

@@ -71,7 +71,7 @@ fiber_base::release()
// so they can be resumed
// protect against concurrent access to joining_
unique_lock< spinlock > lk( joining_mtx_);
BOOST_FOREACH( fiber_base::ptr_t & p, joining_)
BOOST_FOREACH( fiber_base::ptr_t p, joining_)
{
std::stringstream ss;
ss << p->get_id();

View File

@@ -25,8 +25,8 @@ namespace boost {
namespace fibers {
void
fiber::spawn_( detail::fiber_base::ptr_t const& f)
{ detail::scheduler::instance().add( f); }
fiber::spawn_( fiber & f)
{ detail::scheduler::instance().migrate_to( f); }
int
fiber::priority() const

View File

@@ -34,7 +34,7 @@ mutex::lock()
{
while ( LOCKED == state_.exchange( LOCKED, memory_order_seq_cst) )
{
if ( ! this_fiber::is_fiberized() ) ::abort();
BOOST_ASSERT( this_fiber::is_fiberized() );
unique_lock< detail::spinlock > lk( waiting_mtx_);
waiting_.push_back(

View File

@@ -54,16 +54,6 @@ 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()
{
@@ -228,9 +218,14 @@ round_robin::priority( detail::fiber_base::ptr_t const& f, int prio)
}
void
round_robin::migrate_to( BOOST_RV_REF( fiber) f)
round_robin::migrate_to( fiber const& f_)
{
add( detail::scheduler::extract( 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);
}
fiber

View File

@@ -24,7 +24,7 @@ rule fiber-test ( source )
}
test-suite fibers :
# [ fiber-test test_fiber ]
[ fiber-test test_fiber ]
# [ fiber-test test_mutex ]
# [ fiber-test test_condition ]
# [ fiber-test test_generic_locks ]
@@ -34,5 +34,5 @@ test-suite fibers :
# [ fiber-test test_futures ]
# [ fiber-test test_then ]
# [ fiber-test test_round_robin ]
[ fiber-test test_fiber_steeling ]
# [ fiber-test test_fiber_steeling ]
;

View File

@@ -89,10 +89,10 @@ void fn_steel_fibers( boost::fibers::round_robin * other_ds, boost::barrier * b,
if ( f)
{
++( * count);
ds.migrate_to( boost::move( f) );
ds.migrate_to( f);
while ( boost::fibers::run() );
}
BOOST_ASSERT( ! f);
f.detach();
}
}