2
0
mirror of https://github.com/boostorg/fiber.git synced 2026-02-02 20:52:21 +00:00

Merge branch 'feature/pointer' into develop

This commit is contained in:
Oliver Kowalke
2014-03-19 19:56:21 +01:00
30 changed files with 198 additions and 677 deletions

View File

@@ -31,8 +31,7 @@ project boost/fiber
;
lib boost_fiber
: asio/round_robin.cpp
barrier.cpp
: barrier.cpp
condition.cpp
detail/worker_fiber.cpp
detail/scheduler.cpp

View File

@@ -31,13 +31,13 @@ namespace fibers {
struct algorithm : private noncopyable
{
virtual void spawn( detail::worker_fiber::ptr_t const&) = 0;
virtual void spawn( detail::worker_fiber *) = 0;
virtual void priority( detail::worker_fiber::ptr_t const&, int) BOOST_NOEXCEPT = 0;
virtual void priority( detail::worker_fiber *, int) BOOST_NOEXCEPT = 0;
virtual void join( detail::worker_fiber::ptr_t const&) = 0;
virtual void join( detail::worker_fiber *) = 0;
virtual detail::worker_fiber::ptr_t active() BOOST_NOEXCEPT = 0;
virtual detail::worker_fiber * active() BOOST_NOEXCEPT = 0;
virtual void run() = 0;
@@ -51,7 +51,7 @@ struct algorithm : private noncopyable
virtual void yield() = 0;
virtual detail::fiber_base::ptr_t get_main_fiber() = 0;
virtual detail::fiber_base * get_main_fiber() = 0;
virtual ~algorithm() {}
};

View File

@@ -8,10 +8,10 @@
#define BOOST_FIBERS_H
#include <boost/fiber/algorithm.hpp>
#include <boost/fiber/asio/round_robin.hpp>
#include <boost/fiber/asio/spawn.hpp>
#include <boost/fiber/asio/use_future.hpp>
#include <boost/fiber/asio/yield.hpp>
//#include <boost/fiber/asio/round_robin.hpp>
//#include <boost/fiber/asio/spawn.hpp>
//#include <boost/fiber/asio/use_future.hpp>
//#include <boost/fiber/asio/yield.hpp>
#include <boost/fiber/attributes.hpp>
#include <boost/fiber/barrier.hpp>
#include <boost/fiber/bounded_queue.hpp>

View File

@@ -51,7 +51,7 @@ class BOOST_FIBERS_DECL condition : private noncopyable
{
private:
detail::spinlock splk_;
std::deque< detail::fiber_base::ptr_t > waiting_;
std::deque< detail::fiber_base * > waiting_;
public:
condition();
@@ -72,7 +72,7 @@ public:
template< typename LockType >
void wait( LockType & lt)
{
detail::fiber_base::ptr_t n( detail::scheduler::instance()->active() );
detail::fiber_base * n( detail::scheduler::instance()->active() );
try
{
if ( n)
@@ -143,7 +143,7 @@ public:
{
cv_status status = cv_status::no_timeout;
detail::fiber_base::ptr_t n( detail::scheduler::instance()->active() );
detail::fiber_base * n( detail::scheduler::instance()->active() );
try
{
if ( n)

View File

@@ -14,7 +14,6 @@
#include <boost/assert.hpp>
#include <boost/atomic.hpp>
#include <boost/config.hpp>
#include <boost/intrusive_ptr.hpp>
#include <boost/utility.hpp>
#include <boost/fiber/detail/config.hpp>
@@ -34,28 +33,18 @@ namespace detail {
class BOOST_FIBERS_DECL fiber_base : private noncopyable
{
private:
atomic< std::size_t > use_count_;
// std::atomic< std::size_t > use_count_;
// std::size_t use_count_;
protected:
virtual void deallocate_object() = 0;
public:
typedef intrusive_ptr< fiber_base > ptr_t;
class id
{
private:
fiber_base::ptr_t impl_;
fiber_base * impl_;
public:
id() BOOST_NOEXCEPT :
impl_()
impl_( 0)
{}
explicit id( fiber_base::ptr_t impl) BOOST_NOEXCEPT :
explicit id( fiber_base * impl) BOOST_NOEXCEPT :
impl_( impl)
{}
@@ -94,8 +83,7 @@ public:
{ return 0 == impl_; }
};
fiber_base() :
use_count_( 0)
fiber_base()
{}
virtual ~fiber_base() {};
@@ -105,12 +93,6 @@ public:
virtual void set_ready() BOOST_NOEXCEPT = 0;
virtual id get_id() const BOOST_NOEXCEPT = 0;
friend inline void intrusive_ptr_add_ref( fiber_base * p) BOOST_NOEXCEPT
{ ++p->use_count_; }
friend inline void intrusive_ptr_release( fiber_base * p)
{ if ( --p->use_count_ == 0) p->deallocate_object(); }
};
}}}

View File

@@ -7,6 +7,7 @@
#ifndef BOOST_FIBERS_DETAIL_FIFO_H
#define BOOST_FIBERS_DETAIL_FIFO_H
#include <algorithm>
#include <cstddef>
#include <boost/assert.hpp>
@@ -28,27 +29,25 @@ namespace detail {
class fifo : private noncopyable
{
public:
typedef worker_fiber::ptr_t ptr_t;
fifo() BOOST_NOEXCEPT :
head_(),
tail_()
head_( 0),
tail_( 0)
{}
bool empty() const BOOST_NOEXCEPT
{ return 0 == head_.get(); }
{ return 0 == head_; }
std::size_t size() const BOOST_NOEXCEPT
{
std::size_t counter = 0;
for ( ptr_t x = head_; x; x = x->next() )
for ( worker_fiber * x = head_; x; x = x->next() )
++counter;
return counter;
}
void push( ptr_t const& item) BOOST_NOEXCEPT
void push( worker_fiber * item) BOOST_NOEXCEPT
{
BOOST_ASSERT( item);
BOOST_ASSERT( 0 != item);
if ( empty() )
{
@@ -59,23 +58,23 @@ public:
tail_ = tail_->next();
}
ptr_t head() const BOOST_NOEXCEPT
worker_fiber * head() const BOOST_NOEXCEPT
{ return head_; }
void top( ptr_t const& item) BOOST_NOEXCEPT
void top( worker_fiber * item) BOOST_NOEXCEPT
{ head_ = item; }
ptr_t tail() const BOOST_NOEXCEPT
worker_fiber * tail() const BOOST_NOEXCEPT
{ return tail_; }
void tail( ptr_t const& item) BOOST_NOEXCEPT
void tail( worker_fiber * item) BOOST_NOEXCEPT
{ tail_ = item; }
ptr_t pop() BOOST_NOEXCEPT
worker_fiber * pop() BOOST_NOEXCEPT
{
BOOST_ASSERT( ! empty() );
ptr_t item = head_;
worker_fiber * item = head_;
head_ = head_->next();
if ( ! head_)
tail_ = head_;
@@ -84,16 +83,16 @@ public:
return item;
}
ptr_t find( ptr_t const& item) BOOST_NOEXCEPT
worker_fiber * find( worker_fiber * item) BOOST_NOEXCEPT
{
BOOST_ASSERT( item);
BOOST_ASSERT( 0 != item);
for ( ptr_t x = head_; x; x = x->next() )
for ( worker_fiber * x = head_; x; x = x->next() )
if ( item == x) return x;
return ptr_t();
return 0;
}
void erase( ptr_t const& item) BOOST_NOEXCEPT
void erase( worker_fiber * item) BOOST_NOEXCEPT
{
BOOST_ASSERT( item);
BOOST_ASSERT( ! empty() );
@@ -103,9 +102,9 @@ public:
pop();
return;
}
for ( ptr_t x = head_; x; x = x->next() )
for ( worker_fiber * x = head_; x; x = x->next() )
{
ptr_t nxt = x->next();
worker_fiber * nxt = x->next();
if ( ! nxt) return;
if ( item == nxt)
{
@@ -120,9 +119,9 @@ public:
template< typename Queue, typename Fn >
void move_to( Queue & queue, Fn fn)
{
for ( ptr_t f = head_, prev = head_; f; )
for ( worker_fiber * f = head_, * prev = head_; f; )
{
ptr_t nxt = f->next();
worker_fiber * nxt = f->next();
if ( fn( f) )
{
if ( f == head_)
@@ -154,13 +153,13 @@ public:
void swap( fifo & other)
{
head_.swap( other.head_);
tail_.swap( other.tail_);
std::swap( head_, other.head_);
std::swap( tail_, other.tail_);
}
private:
ptr_t head_;
ptr_t tail_;
worker_fiber * head_;
worker_fiber * tail_;
};
}}}

View File

@@ -23,7 +23,8 @@ enum flag_t
{
flag_interruption_blocked = 1 << 0,
flag_interruption_requested = 1 << 1,
flag_thread_affinity = 1 << 2
flag_thread_affinity = 1 << 2,
flag_detached = 1 << 3
};
}}}

View File

@@ -23,10 +23,8 @@ namespace detail {
class main_fiber : public fiber_base
{
public:
static ptr_t make_pointer( main_fiber & n) {
ptr_t p( & n);
intrusive_ptr_add_ref( p.get() );
return p;
static main_fiber * make_pointer( main_fiber & n) {
return & n;
}
main_fiber() :
@@ -40,9 +38,6 @@ public:
void set_ready() BOOST_NOEXCEPT
{ ready_ = true; }
void deallocate_object()
{}
id get_id() const BOOST_NOEXCEPT
{ return id( const_cast< main_fiber * >( this) ); }

View File

@@ -79,7 +79,7 @@ private:
public:
template< typename F >
static fiber_base::ptr_t extract( F const& f) BOOST_NOEXCEPT
static fiber_base * extract( F const& f) BOOST_NOEXCEPT
{ return f.impl_; }
static algorithm * instance()

View File

@@ -46,9 +46,6 @@ namespace coro = boost::coroutines;
class BOOST_FIBERS_DECL worker_fiber : public fiber_base
{
public:
typedef intrusive_ptr< worker_fiber > ptr_t;
private:
enum state_t
{
@@ -83,20 +80,20 @@ private:
> coro_t;
fss_data_t fss_data_;
ptr_t nxt_;
worker_fiber * nxt_;
clock_type::time_point tp_;
void trampoline_( coro_t::yield_type &);
protected:
coro_t::yield_type * callee_;
coro_t::call_type caller_;
atomic< state_t > state_;
atomic< int > flags_;
atomic< int > priority_;
exception_ptr except_;
spinlock splk_;
std::vector< ptr_t > waiting_;
coro_t::yield_type * callee_;
coro_t::call_type caller_;
atomic< state_t > state_;
atomic< int > flags_;
atomic< int > priority_;
exception_ptr except_;
spinlock splk_;
std::vector< worker_fiber * > waiting_;
void release();
@@ -116,7 +113,13 @@ public:
void priority( int prio) BOOST_NOEXCEPT
{ priority_ = prio; }
bool join( ptr_t const&);
bool join( worker_fiber *);
bool detached() const BOOST_NOEXCEPT
{ return 0 != ( flags_.load() & flag_detached); }
void detach() BOOST_NOEXCEPT
{ flags_ |= flag_detached; }
bool interruption_blocked() const BOOST_NOEXCEPT
{ return 0 != ( flags_.load() & flag_interruption_blocked); }
@@ -177,11 +180,9 @@ public:
void * data,
bool cleanup_existing);
bool has_exception() const BOOST_NOEXCEPT
exception_ptr exception() const BOOST_NOEXCEPT
{ return except_; }
void rethrow() const;
void resume( worker_fiber * f)
{
if ( 0 == f)
@@ -213,14 +214,14 @@ public:
BOOST_ASSERT( is_running() ); // set by the scheduler-algorithm
}
ptr_t const& next() const
worker_fiber * next() const
{ return nxt_; }
void next( ptr_t const& nxt)
void next( worker_fiber * nxt)
{ nxt_ = nxt; }
void next_reset()
{ nxt_.reset(); }
{ nxt_ = 0; }
clock_type::time_point const& time_point() const
{ return tp_; }
@@ -230,6 +231,8 @@ public:
void time_point_reset()
{ tp_ = (clock_type::time_point::max)(); }
virtual void deallocate() = 0;
};
}}}

View File

@@ -1,189 +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_FIBER_H
#define BOOST_FIBERS_DETAIL_WORKER_FIBER_H
#include <cstddef>
#include <map>
#include <vector>
#include <boost/assert.hpp>
#include <boost/atomic.hpp>
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/exception_ptr.hpp>
#include <boost/intrusive_ptr.hpp>
#include <boost/move/move.hpp>
#include <boost/utility.hpp>
#include <boost/fiber/attributes.hpp>
#include <boost/fiber/detail/config.hpp>
#include <boost/fiber/detail/fiber_base.hpp>
#include <boost/fiber/detail/flags.hpp>
#include <boost/fiber/detail/fss.hpp>
#include <boost/fiber/detail/spinlock.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
# if defined(BOOST_MSVC)
# pragma warning(push)
# pragma warning(disable:4251)
# endif
namespace boost {
namespace fibers {
namespace detail {
class BOOST_FIBERS_DECL worker_fiber : public fiber_base
{
public:
typedef intrusive_ptr< worker_fiber > ptr_t;
private:
enum state_t
{
READY = 0,
RUNNING,
WAITING,
TERMINATED
};
struct BOOST_FIBERS_DECL fss_data
{
void * vp;
fss_cleanup_function::ptr_t cleanup_function;
fss_data() :
vp( 0), cleanup_function( 0)
{}
fss_data(
void * vp_,
fss_cleanup_function::ptr_t const& fn) :
vp( vp_), cleanup_function( fn)
{ BOOST_ASSERT( cleanup_function); }
void do_cleanup()
{ ( * cleanup_function)( vp); }
};
typedef std::map< uintptr_t, fss_data > fss_data_t;
fss_data_t fss_data_;
ptr_t nxt_;
clock_type::time_point tp_;
protected:
atomic< state_t > state_;
atomic< int > flags_;
atomic< int > priority_;
exception_ptr except_;
spinlock splk_;
std::vector< ptr_t > waiting_;
void release();
public:
worker_fiber();
virtual ~worker_fiber();
id get_id() const BOOST_NOEXCEPT
{ return id( const_cast< worker_fiber * >( this) ); }
int priority() const BOOST_NOEXCEPT
{ return priority_; }
void priority( int prio) BOOST_NOEXCEPT
{ priority_ = prio; }
bool join( ptr_t const&);
bool interruption_blocked() const BOOST_NOEXCEPT
{ return 0 != ( flags_.load() & flag_interruption_blocked); }
void interruption_blocked( bool blck) BOOST_NOEXCEPT;
bool interruption_requested() const BOOST_NOEXCEPT
{ return 0 != ( flags_.load() & flag_interruption_requested); }
void request_interruption( bool req) BOOST_NOEXCEPT;
bool thread_affinity() const BOOST_NOEXCEPT
{ return 0 != ( flags_.load() & flag_thread_affinity); }
void thread_affinity( bool req) BOOST_NOEXCEPT;
bool is_terminated() const BOOST_NOEXCEPT
{ return TERMINATED == state_; }
bool is_ready() const BOOST_NOEXCEPT
{ return READY == state_; }
bool is_running() const BOOST_NOEXCEPT
{ return RUNNING == state_; }
bool is_waiting() const BOOST_NOEXCEPT
{ return WAITING == state_; }
void set_terminated() BOOST_NOEXCEPT;
void set_ready() BOOST_NOEXCEPT;
void set_running() BOOST_NOEXCEPT;
void set_waiting() BOOST_NOEXCEPT;
void * get_fss_data( void const* vp) const;
void set_fss_data(
void const* vp,
fss_cleanup_function::ptr_t const& cleanup_fn,
void * data,
bool cleanup_existing);
bool has_exception() const BOOST_NOEXCEPT
{ return except_; }
void rethrow() const;
virtual void resume() = 0;
virtual void suspend() = 0;
ptr_t const& next() const
{ return nxt_; }
void next( ptr_t const& nxt)
{ nxt_ = nxt; }
void next_reset()
{ nxt_.reset(); }
clock_type::time_point const& time_point() const
{ return tp_; }
void time_point( clock_type::time_point const& tp)
{ tp_ = tp; }
void time_point_reset()
{ tp_ = (clock_type::time_point::max)(); }
};
}}}
# if defined(BOOST_MSVC)
# pragma warning(pop)
# endif
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_FIBERS_DETAIL_WORKER_FIBER_H

View File

@@ -1,245 +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_FIBER_H
#define BOOST_FIBERS_DETAIL_WORKER_FIBER_H
#include <cstddef>
#include <map>
#include <vector>
#include <boost/assert.hpp>
#include <boost/atomic.hpp>
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/coroutine/symmetric_coroutine.hpp>
#include <boost/exception_ptr.hpp>
#include <boost/intrusive_ptr.hpp>
#include <boost/move/move.hpp>
#include <boost/utility.hpp>
#include <boost/fiber/attributes.hpp>
#include <boost/fiber/detail/config.hpp>
#include <boost/fiber/detail/fiber_base.hpp>
#include <boost/fiber/detail/flags.hpp>
#include <boost/fiber/detail/fss.hpp>
#include <boost/fiber/detail/spinlock.hpp>
#include <boost/fiber/exceptions.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
# if defined(BOOST_MSVC)
# pragma warning(push)
# pragma warning(disable:4251)
# endif
namespace boost {
namespace fibers {
namespace detail {
namespace coro = boost::coroutines;
class BOOST_FIBERS_DECL worker_fiber : public fiber_base
{
public:
typedef intrusive_ptr< worker_fiber > ptr_t;
private:
enum state_t
{
READY = 0,
RUNNING,
WAITING,
TERMINATED
};
struct BOOST_FIBERS_DECL fss_data
{
void * vp;
fss_cleanup_function::ptr_t cleanup_function;
fss_data() :
vp( 0), cleanup_function( 0)
{}
fss_data(
void * vp_,
fss_cleanup_function::ptr_t const& fn) :
vp( vp_), cleanup_function( fn)
{ BOOST_ASSERT( cleanup_function); }
void do_cleanup()
{ ( * cleanup_function)( vp); }
};
typedef std::map< uintptr_t, fss_data > fss_data_t;
typedef coro::symmetric_coroutine<
void
> coro_t;
fss_data_t fss_data_;
ptr_t nxt_;
clock_type::time_point tp_;
void trampoline_( coro_t::yield_type &);
protected:
coro_t::yield_type * callee_;
coro_t::call_type caller_;
atomic< state_t > state_;
atomic< int > flags_;
atomic< int > priority_;
exception_ptr except_;
spinlock splk_;
std::vector< ptr_t > waiting_;
void release();
virtual void run() = 0;
public:
worker_fiber( attributes const&);
virtual ~worker_fiber();
id get_id() const BOOST_NOEXCEPT
{ return id( const_cast< worker_fiber * >( this) ); }
int priority() const BOOST_NOEXCEPT
{ return priority_; }
void priority( int prio) BOOST_NOEXCEPT
{ priority_ = prio; }
bool join( ptr_t const&);
bool interruption_blocked() const BOOST_NOEXCEPT
{ return 0 != ( flags_.load() & flag_interruption_blocked); }
void interruption_blocked( bool blck) BOOST_NOEXCEPT;
bool interruption_requested() const BOOST_NOEXCEPT
{ return 0 != ( flags_.load() & flag_interruption_requested); }
void request_interruption( bool req) BOOST_NOEXCEPT;
bool thread_affinity() const BOOST_NOEXCEPT
{ return 0 != ( flags_.load() & flag_thread_affinity); }
void thread_affinity( bool req) BOOST_NOEXCEPT;
bool is_terminated() const BOOST_NOEXCEPT
{ return TERMINATED == state_; }
bool is_ready() const BOOST_NOEXCEPT
{ return READY == state_; }
bool is_running() const BOOST_NOEXCEPT
{ return RUNNING == state_; }
bool is_waiting() const BOOST_NOEXCEPT
{ return WAITING == state_; }
void set_terminated() BOOST_NOEXCEPT
{
state_t previous = state_.exchange( TERMINATED);
BOOST_ASSERT( RUNNING == previous);
}
void set_ready() BOOST_NOEXCEPT
{
state_t previous = state_.exchange( READY);
BOOST_ASSERT( WAITING == previous || RUNNING == previous || READY == previous);
}
void set_running() BOOST_NOEXCEPT
{
state_t previous = state_.exchange( RUNNING);
BOOST_ASSERT( READY == previous);
}
void set_waiting() BOOST_NOEXCEPT
{
state_t previous = state_.exchange( WAITING);
BOOST_ASSERT( RUNNING == previous);
}
void * get_fss_data( void const* vp) const;
void set_fss_data(
void const* vp,
fss_cleanup_function::ptr_t const& cleanup_fn,
void * data,
bool cleanup_existing);
bool has_exception() const BOOST_NOEXCEPT
{ return except_; }
void rethrow() const;
void resume( worker_fiber * f)
{
if ( 0 == f)
{
BOOST_ASSERT( caller_);
BOOST_ASSERT( is_running() ); // set by the scheduler-algorithm
// called from main-fiber
caller_();
}
else
{
// caller from worker-fiber f
BOOST_ASSERT( caller_);
BOOST_ASSERT( is_running() ); // set by the scheduler-algorithm
BOOST_ASSERT( f->callee_);
( * f->callee_)( caller_);
}
}
void suspend()
{
BOOST_ASSERT( callee_);
BOOST_ASSERT( * callee_);
( * callee_)();
BOOST_ASSERT( is_running() ); // set by the scheduler-algorithm
}
ptr_t const& next() const
{ return nxt_; }
void next( ptr_t const& nxt)
{ nxt_ = nxt; }
void next_reset()
{ nxt_.reset(); }
clock_type::time_point const& time_point() const
{ return tp_; }
void time_point( clock_type::time_point const& tp)
{ tp_ = tp; }
void time_point_reset()
{ tp_ = (clock_type::time_point::max)(); }
};
}}}
# if defined(BOOST_MSVC)
# pragma warning(pop)
# endif
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_FIBERS_DETAIL_WORKER_FIBER_H

View File

@@ -95,7 +95,7 @@ public:
}
#endif
void deallocate_object()
void deallocate()
{ destroy_( alloc_, this); }
private:

View File

@@ -7,6 +7,7 @@
#ifndef BOOST_FIBERS_FIBER_H
#define BOOST_FIBERS_FIBER_H
#include <algorithm>
#include <cstddef>
#include <exception>
#include <memory>
@@ -49,9 +50,8 @@ private:
friend class detail::scheduler;
typedef detail::worker_fiber base_t;
typedef base_t::ptr_t ptr_t;
ptr_t impl_;
detail::worker_fiber * impl_;
BOOST_MOVABLE_BUT_NOT_COPYABLE( fiber);
@@ -61,10 +61,10 @@ public:
typedef detail::worker_fiber::id id;
fiber() BOOST_NOEXCEPT :
impl_()
impl_( 0)
{}
explicit fiber( ptr_t imp) BOOST_NOEXCEPT :
explicit fiber( detail::worker_fiber * imp) BOOST_NOEXCEPT :
impl_( imp)
{}
@@ -75,15 +75,13 @@ public:
explicit fiber( fiber_fn fn, attributes const& attr = attributes(),
stack_allocator const& stack_alloc = stack_allocator(),
std::allocator< fiber > const& alloc = std::allocator< fiber >() ) :
impl_()
impl_( 0)
{
typedef detail::worker_object<
fiber_fn, std::allocator< fiber >
> object_t;
object_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) object_t( forward< fiber_fn >( fn), attr, a) );
impl_ = ::new( a.allocate( 1) ) object_t( forward< fiber_fn >( fn), attr, a);
start_fiber_();
}
@@ -91,15 +89,13 @@ public:
explicit fiber( fiber_fn fn, attributes const& attr,
StackAllocator const& stack_alloc,
std::allocator< fiber > const& alloc = std::allocator< fiber >() ) :
impl_()
impl_( 0)
{
typedef detail::worker_object<
fiber_fn, std::allocator< fiber >
> object_t;
typename object_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) object_t( forward< fiber_fn >( fn), attr, a) );
impl_ = ::new( a.allocate( 1) ) object_t( forward< fiber_fn >( fn), attr, a);
start_fiber_();
}
@@ -107,15 +103,13 @@ public:
explicit fiber( fiber_fn fn, attributes const& attr,
StackAllocator const& stack_alloc,
Allocator const& alloc) :
impl_()
impl_( 0)
{
typedef detail::worker_object<
fiber_fn, Allocator
> object_t;
typename object_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) object_t( forward< fiber_fn >( fn), attr, a) );
impl_ = ::new( a.allocate( 1) ) object_t( forward< fiber_fn >( fn), attr, a);
start_fiber_();
}
#endif
@@ -123,15 +117,13 @@ public:
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 >() ) :
impl_()
impl_( 0)
{
typedef detail::worker_object<
Fn, std::allocator< fiber >
> object_t;
typename object_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, a) );
impl_ = ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, a);
start_fiber_();
}
@@ -139,15 +131,13 @@ public:
explicit fiber( BOOST_RV_REF( Fn) fn, attributes const& attr,
StackAllocator const& stack_alloc,
std::allocator< fiber > const& alloc = std::allocator< fiber >() ) :
impl_()
impl_( 0)
{
typedef detail::worker_object<
Fn, std::allocator< fiber >
> object_t;
typename object_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, a) );
impl_ = ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, a);
start_fiber_();
}
@@ -155,15 +145,13 @@ public:
explicit fiber( BOOST_RV_REF( Fn) fn, attributes const& attr,
StackAllocator const& stack_alloc,
Allocator const& alloc) :
impl_()
impl_( 0)
{
typedef detail::worker_object<
Fn, Allocator
> object_t;
typename object_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, a) );
impl_ = ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, a);
start_fiber_();
}
#else
@@ -171,15 +159,13 @@ public:
explicit fiber( Fn fn, attributes const& attr = attributes(),
stack_allocator const& stack_alloc = stack_allocator(),
std::allocator< fiber > const& alloc = std::allocator< fiber >() ) :
impl_()
impl_( 0)
{
typedef detail::worker_object<
Fn, std::allocator< fiber >
> object_t;
typename object_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) object_t( fn, attr, a) );
impl_ = ::new( a.allocate( 1) ) object_t( fn, attr, a);
start_fiber_();
}
@@ -187,15 +173,13 @@ public:
explicit fiber( Fn fn, attributes const& attr,
StackAllocator const& stack_alloc,
std::allocator< fiber > const& alloc = std::allocator< fiber >() ) :
impl_()
impl_( 0)
{
typedef detail::worker_object<
Fn, std::allocator< fiber >
> object_t;
typename object_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) object_t( fn, attr, a) );
impl_ = ::new( a.allocate( 1) ) object_t( fn, attr, a);
start_fiber_();
}
@@ -203,15 +187,13 @@ public:
explicit fiber( Fn fn, attributes const& attr,
StackAllocator const& stack_alloc,
Allocator const& alloc) :
impl_()
impl_( 0)
{
typedef detail::worker_object<
Fn, Allocator
> object_t;
typename object_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) object_t( fn, attr, a) );
impl_ = ::new( a.allocate( 1) ) object_t( fn, attr, a);
start_fiber_();
}
@@ -219,15 +201,13 @@ public:
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 >() ) :
impl_()
impl_( 0)
{
typedef detail::worker_object<
Fn, std::allocator< fiber >
> object_t;
typename object_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) object_t( fn, attr, a) );
impl_ = ::new( a.allocate( 1) ) object_t( fn, attr, a);
start_fiber_();
}
@@ -235,15 +215,13 @@ public:
explicit fiber( BOOST_RV_REF( Fn) fn, attributes const& attr,
StackAllocator const& stack_alloc,
std::allocator< fiber > const& alloc = std::allocator< fiber >() ) :
impl_()
impl_( 0)
{
typedef detail::worker_object<
Fn, std::allocator< fiber >
> object_t;
typename object_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) object_t( fn, attr, a) );
impl_ = ::new( a.allocate( 1) ) object_t( fn, attr, a);
start_fiber_();
}
@@ -251,24 +229,29 @@ public:
explicit fiber( BOOST_RV_REF( Fn) fn, attributes const& attr,
StackAllocator const& stack_alloc,
Allocator const& alloc) :
impl_()
impl_( 0)
{
typedef detail::worker_object<
Fn, Allocator
> object_t;
typename object_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) object_t( fn, attr, a) );
impl_ = ::new( a.allocate( 1) ) object_t( fn, attr, a);
start_fiber_();
}
#endif
~fiber()
{ if ( joinable() ) std::terminate(); }
{
if ( joinable() ) std::terminate();
if ( 0 != impl_)
{
impl_->deallocate();
impl_ = 0;
}
}
fiber( BOOST_RV_REF( fiber) other) BOOST_NOEXCEPT :
impl_()
impl_( 0)
{ swap( other); }
fiber & operator=( BOOST_RV_REF( fiber) other) BOOST_NOEXCEPT
@@ -285,10 +268,10 @@ public:
{ return ! impl_ || impl_->is_terminated(); }
void swap( fiber & other) BOOST_NOEXCEPT
{ impl_.swap( other.impl_); }
{ std::swap( impl_, other.impl_); }
bool joinable() const BOOST_NOEXCEPT
{ return 0 != impl_.get() /* && ! impl_->is_terminated() */; }
{ return 0 != impl_ /* && ! impl_->is_terminated() */; }
id get_id() const BOOST_NOEXCEPT
{ return impl_ ? impl_->get_id() : id(); }

View File

@@ -39,12 +39,10 @@ private:
UNLOCKED
};
detail::spinlock splk_;
state_t state_;
detail::worker_fiber::id owner_;
std::deque<
detail::fiber_base::ptr_t
> waiting_;
detail::spinlock splk_;
state_t state_;
detail::worker_fiber::id owner_;
std::deque< detail::fiber_base * > waiting_;
public:
typedef unique_lock< mutex > scoped_lock;

View File

@@ -25,7 +25,7 @@ namespace this_fiber {
inline
fibers::fiber::id get_id() BOOST_NOEXCEPT
{
return fibers::detail::scheduler::instance()->active()
return 0 != fibers::detail::scheduler::instance()->active()
? fibers::detail::scheduler::instance()->active()->get_id()
: fibers::fiber::id();
}
@@ -33,7 +33,7 @@ fibers::fiber::id get_id() BOOST_NOEXCEPT
inline
void yield()
{
if ( fibers::detail::scheduler::instance()->active() )
if ( 0 != fibers::detail::scheduler::instance()->active() )
fibers::detail::scheduler::instance()->yield();
else
fibers::detail::scheduler::instance()->run();
@@ -42,7 +42,7 @@ void yield()
inline
void sleep_until( fibers::clock_type::time_point const& sleep_time)
{
if ( fibers::detail::scheduler::instance()->active() )
if ( 0 != fibers::detail::scheduler::instance()->active() )
{
fibers::detail::spinlock splk;
unique_lock< fibers::detail::spinlock > lk( splk);
@@ -65,7 +65,7 @@ void sleep_for( chrono::duration< Rep, Period > const& timeout_duration)
inline
bool thread_affinity() BOOST_NOEXCEPT
{
return fibers::detail::scheduler::instance()->active()
return 0 != fibers::detail::scheduler::instance()->active()
? fibers::detail::scheduler::instance()->active()->thread_affinity()
: true;
}
@@ -73,7 +73,7 @@ bool thread_affinity() BOOST_NOEXCEPT
inline
void thread_affinity( bool req) BOOST_NOEXCEPT
{
if ( fibers::detail::scheduler::instance()->active() )
if ( 0 != fibers::detail::scheduler::instance()->active() )
fibers::detail::scheduler::instance()->active()->thread_affinity( req);
}

View File

@@ -42,13 +42,11 @@ private:
UNLOCKED
};
detail::spinlock splk_;
state_t state_;
detail::worker_fiber::id owner_;
std::size_t count_;
std::deque<
detail::fiber_base::ptr_t
> waiting_;
detail::spinlock splk_;
state_t state_;
detail::worker_fiber::id owner_;
std::size_t count_;
std::deque< detail::fiber_base * > waiting_;
public:
typedef unique_lock< recursive_mutex > scoped_lock;

View File

@@ -42,13 +42,11 @@ private:
UNLOCKED
};
detail::spinlock splk_;
state_t state_;
detail::worker_fiber::id owner_;
std::size_t count_;
std::deque<
detail::fiber_base::ptr_t
> waiting_;
detail::spinlock splk_;
state_t state_;
detail::worker_fiber::id owner_;
std::size_t count_;
std::deque< detail::fiber_base * > waiting_;
public:
typedef unique_lock< recursive_timed_mutex > scoped_lock;

View File

@@ -46,27 +46,27 @@ private:
typedef detail::fifo wqueue_t;
typedef detail::fifo rqueue_t;
detail::worker_fiber::ptr_t active_fiber_;
detail::worker_fiber * active_fiber_;
wqueue_t wqueue_;
rqueue_t rqueue_;
detail::main_fiber mn_;
detail::worker_fiber::ptr_t pick_next_();
detail::worker_fiber * pick_next_();
void resume_( detail::worker_fiber::ptr_t const&);
void resume_( detail::worker_fiber *);
public:
round_robin() BOOST_NOEXCEPT;
~round_robin() BOOST_NOEXCEPT;
void spawn( detail::worker_fiber::ptr_t const&);
void spawn( detail::worker_fiber *);
void priority( detail::worker_fiber::ptr_t const&, int) BOOST_NOEXCEPT;
void priority( detail::worker_fiber *, int) BOOST_NOEXCEPT;
void join( detail::worker_fiber::ptr_t const&);
void join( detail::worker_fiber *);
detail::worker_fiber::ptr_t active() BOOST_NOEXCEPT
detail::worker_fiber * active() BOOST_NOEXCEPT
{ return active_fiber_; }
void run();
@@ -77,8 +77,11 @@ public:
void yield();
detail::fiber_base::ptr_t get_main_fiber()
{ return detail::fiber_base::ptr_t( new detail::main_fiber() ); }
// FIXME: must be removed
// allocate main_fiber on stack of mutext, condition, etc.
// and pass address of main_fiber to wait-container
detail::fiber_base * get_main_fiber()
{ return new detail::main_fiber(); }
};
}}

View File

@@ -39,12 +39,10 @@ private:
UNLOCKED
};
detail::spinlock splk_;
state_t state_;
detail::worker_fiber::id owner_;
std::deque<
detail::fiber_base::ptr_t
> waiting_;
detail::spinlock splk_;
state_t state_;
detail::worker_fiber::id owner_;
std::deque< detail::fiber_base * > waiting_;
public:
typedef unique_lock< timed_mutex > scoped_lock;

View File

@@ -28,12 +28,12 @@ condition::~condition()
void
condition::notify_one()
{
detail::fiber_base::ptr_t n;
detail::fiber_base * n = 0;
unique_lock< detail::spinlock > lk( splk_);
// get one waiting fiber
if ( ! waiting_.empty() ) {
n.swap( waiting_.front() );
n = waiting_.front();
waiting_.pop_front();
}
lk.unlock();
@@ -45,7 +45,7 @@ condition::notify_one()
void
condition::notify_all()
{
std::deque< detail::fiber_base::ptr_t > waiting;
std::deque< detail::fiber_base * > waiting;
unique_lock< detail::spinlock > lk( splk_);
// get all waiting fibers
@@ -55,7 +55,7 @@ condition::notify_all()
// notify all waiting fibers
while ( ! waiting.empty() )
{
detail::fiber_base::ptr_t n( waiting.front() );
detail::fiber_base * n( waiting.front() );
waiting.pop_front();
BOOST_ASSERT( n);
n->set_ready();

View File

@@ -22,7 +22,7 @@ spinlock::spinlock() :
void
spinlock::lock()
{
bool is_fiber = 0 != scheduler::instance()->active().get();
bool is_fiber = 0 != scheduler::instance()->active();
for (;;)
{
// access to CPU's cache

View File

@@ -60,7 +60,7 @@ worker_fiber::trampoline_( coro_t::yield_type & yield)
worker_fiber::worker_fiber( attributes const& attrs) :
fiber_base(),
fss_data_(),
nxt_(),
nxt_( 0),
tp_( (clock_type::time_point::max)() ),
callee_( 0),
caller_(
@@ -84,7 +84,7 @@ worker_fiber::release()
{
BOOST_ASSERT( is_terminated() );
std::vector< ptr_t > waiting;
std::vector< worker_fiber * > waiting;
// get all waiting fibers
splk_.lock();
@@ -92,7 +92,7 @@ worker_fiber::release()
splk_.unlock();
// notify all waiting fibers
BOOST_FOREACH( worker_fiber::ptr_t p, waiting)
BOOST_FOREACH( worker_fiber * p, waiting)
{ p->set_ready(); }
// release all fiber-specific-pointers
@@ -101,7 +101,7 @@ worker_fiber::release()
}
bool
worker_fiber::join( ptr_t const& p)
worker_fiber::join( worker_fiber * p)
{
unique_lock< spinlock > lk( splk_);
if ( is_terminated() ) return false;
@@ -174,14 +174,6 @@ worker_fiber::set_fss_data(
fss_data( data, cleanup_fn) ) );
}
void
worker_fiber::rethrow() const
{
BOOST_ASSERT( has_exception() );
rethrow_exception( except_);
}
}}}
#ifdef BOOST_HAS_ABI_HEADERS

View File

@@ -77,11 +77,13 @@ fiber::join()
detail::scheduler::instance()->join( impl_);
ptr_t tmp;
tmp.swap( impl_);
detail::worker_fiber * tmp = 0;
std::swap( tmp, impl_);
// check if joined fiber was interrupted
if ( tmp->has_exception() )
tmp->rethrow();
exception_ptr except( tmp->exception() );
tmp->deallocate();
if ( except)
rethrow_exception( except);
}
void
@@ -96,7 +98,8 @@ fiber::detach() BOOST_NOEXCEPT
system::errc::invalid_argument, "boost fiber: fiber not joinable") );
}
impl_.reset();
impl_->detach();
impl_ = 0;
}
void

View File

@@ -50,14 +50,14 @@ restore_interruption::~restore_interruption() BOOST_NOEXCEPT
bool interruption_enabled() BOOST_NOEXCEPT
{
fibers::detail::worker_fiber::ptr_t f( fibers::detail::scheduler::instance()->active() );
return f && ! f->interruption_blocked();
fibers::detail::worker_fiber * f = fibers::detail::scheduler::instance()->active();
return 0 != f && ! f->interruption_blocked();
}
bool interruption_requested() BOOST_NOEXCEPT
{
fibers::detail::worker_fiber::ptr_t f( fibers::detail::scheduler::instance()->active() );
if ( ! f) return false;
fibers::detail::worker_fiber * f = fibers::detail::scheduler::instance()->active();
if ( 0 == f) return false;
return f->interruption_requested();
}

View File

@@ -37,8 +37,8 @@ mutex::~mutex()
void
mutex::lock()
{
detail::fiber_base::ptr_t n( detail::scheduler::instance()->active() );
if ( n)
detail::fiber_base * n( detail::scheduler::instance()->active() );
if ( 0 != n)
{
for (;;)
{
@@ -118,10 +118,10 @@ mutex::unlock()
BOOST_ASSERT( this_fiber::get_id() == owner_);
unique_lock< detail::spinlock > lk( splk_);
detail::fiber_base::ptr_t n;
detail::fiber_base * n = 0;
if ( ! waiting_.empty() )
{
n.swap( waiting_.front() );
n = waiting_.front();
waiting_.pop_front();
}
owner_ = detail::worker_fiber::id();

View File

@@ -39,8 +39,8 @@ recursive_mutex::~recursive_mutex()
void
recursive_mutex::lock()
{
detail::fiber_base::ptr_t n( detail::scheduler::instance()->active() );
if ( n)
detail::fiber_base * n( detail::scheduler::instance()->active() );
if ( 0 != n)
{
for (;;)
{
@@ -138,13 +138,13 @@ recursive_mutex::unlock()
BOOST_ASSERT( this_fiber::get_id() == owner_);
unique_lock< detail::spinlock > lk( splk_);
detail::fiber_base::ptr_t n;
detail::fiber_base * n = 0;
if ( 0 == --count_)
{
if ( ! waiting_.empty() )
{
n.swap( waiting_.front() );
n = waiting_.front();
waiting_.pop_front();
}
owner_ = detail::worker_fiber::id();

View File

@@ -39,8 +39,8 @@ recursive_timed_mutex::~recursive_timed_mutex()
void
recursive_timed_mutex::lock()
{
detail::fiber_base::ptr_t n( detail::scheduler::instance()->active() );
if ( n)
detail::fiber_base * n( detail::scheduler::instance()->active() );
if ( 0 != n)
{
for (;;)
{
@@ -134,7 +134,7 @@ recursive_timed_mutex::try_lock()
bool
recursive_timed_mutex::try_lock_until( clock_type::time_point const& timeout_time)
{
detail::fiber_base::ptr_t n( detail::scheduler::instance()->active() );
detail::fiber_base * n( detail::scheduler::instance()->active() );
if ( n)
{
for (;;)
@@ -231,13 +231,13 @@ recursive_timed_mutex::unlock()
BOOST_ASSERT( this_fiber::get_id() == owner_);
unique_lock< detail::spinlock > lk( splk_);
detail::fiber_base::ptr_t n;
detail::fiber_base * n = 0;
if ( 0 == --count_)
{
if ( ! waiting_.empty() )
{
n.swap( waiting_.front() );
n = waiting_.front();
waiting_.pop_front();
}
owner_ = detail::worker_fiber::id();

View File

@@ -28,7 +28,7 @@
namespace boost {
namespace fibers {
bool fetch_ready( detail::worker_fiber::ptr_t & f)
bool fetch_ready( detail::worker_fiber * f)
{
BOOST_ASSERT( ! f->is_running() );
BOOST_ASSERT( ! f->is_terminated() );
@@ -40,23 +40,23 @@ bool fetch_ready( detail::worker_fiber::ptr_t & f)
return f->is_ready();
}
detail::worker_fiber::ptr_t
detail::worker_fiber *
round_robin::pick_next_()
{
detail::worker_fiber::ptr_t victim;
detail::worker_fiber * victim = 0;
if ( ! rqueue_.empty() )
victim = rqueue_.pop();
return victim;
}
void
round_robin::resume_( detail::worker_fiber::ptr_t const& f)
round_robin::resume_( detail::worker_fiber * f)
{
BOOST_ASSERT( f);
BOOST_ASSERT( f->is_ready() );
// store active fiber in local var
detail::worker_fiber::ptr_t tmp = active_fiber_;
detail::worker_fiber * tmp( active_fiber_);
// assign new fiber to active fiber
active_fiber_ = f;
// set active fiber to state_running
@@ -65,16 +65,19 @@ round_robin::resume_( detail::worker_fiber::ptr_t const& f)
// this might happend if fiber calls yield() and no
// other fiber is in the ready-queue
if ( tmp != active_fiber_)
{
// resume active-fiber == start or yield to
active_fiber_->resume( tmp.get() );
active_fiber_->resume( tmp);
if ( active_fiber_->detached() && active_fiber_->is_terminated() )
active_fiber_->deallocate();
}
//BOOST_ASSERT( f == active_fiber_);
// reset active fiber to previous
active_fiber_ = tmp;
}
round_robin::round_robin() BOOST_NOEXCEPT :
active_fiber_(),
active_fiber_( 0),
wqueue_(),
rqueue_(),
mn_()
@@ -92,7 +95,7 @@ round_robin::~round_robin() BOOST_NOEXCEPT
}
void
round_robin::spawn( detail::worker_fiber::ptr_t const& f)
round_robin::spawn( detail::worker_fiber * f)
{ rqueue_.push( f); }
void
@@ -106,7 +109,7 @@ round_robin::run()
// pop new fiber from ready-queue which is not complete
// (example: fiber in ready-queue could be canceled by active-fiber)
detail::worker_fiber::ptr_t f = pick_next_();
detail::worker_fiber * f( pick_next_() );
if ( f)
{
BOOST_ASSERT_MSG( f->is_ready(), "fiber with invalid state in ready-queue");
@@ -163,7 +166,7 @@ round_robin::yield()
}
void
round_robin::join( detail::worker_fiber::ptr_t const& f)
round_robin::join( detail::worker_fiber * f)
{
BOOST_ASSERT( f);
BOOST_ASSERT( f != active_fiber_);
@@ -195,7 +198,7 @@ round_robin::join( detail::worker_fiber::ptr_t const& f)
}
void
round_robin::priority( detail::worker_fiber::ptr_t const& f, int prio) BOOST_NOEXCEPT
round_robin::priority( detail::worker_fiber * f, int prio) BOOST_NOEXCEPT
{
BOOST_ASSERT( f);

View File

@@ -37,7 +37,7 @@ timed_mutex::~timed_mutex()
void
timed_mutex::lock()
{
detail::fiber_base::ptr_t n( detail::scheduler::instance()->active() );
detail::fiber_base * n( detail::scheduler::instance()->active() );
if ( n)
{
for (;;)
@@ -114,7 +114,7 @@ timed_mutex::try_lock()
bool
timed_mutex::try_lock_until( clock_type::time_point const& timeout_time)
{
detail::fiber_base::ptr_t n( detail::scheduler::instance()->active() );
detail::fiber_base * n( detail::scheduler::instance()->active() );
if ( n)
{
for (;;)
@@ -199,11 +199,11 @@ timed_mutex::unlock()
BOOST_ASSERT( this_fiber::get_id() == owner_);
unique_lock< detail::spinlock > lk( splk_);
detail::fiber_base::ptr_t n;
detail::fiber_base * n = 0;
if ( ! waiting_.empty() )
{
n.swap( waiting_.front() );
n = waiting_.front();
waiting_.pop_front();
}
owner_ = detail::worker_fiber::id();