2
0
mirror of https://github.com/boostorg/fiber.git synced 2026-02-10 23:32:28 +00:00

use execution_context

This commit is contained in:
Oliver Kowalke
2014-11-24 19:58:48 +01:00
parent 9bd1c0cd0f
commit ddbdd91ced
5 changed files with 40 additions and 122 deletions

View File

@@ -17,6 +17,7 @@
#include <boost/chrono/system_clocks.hpp>
#include <boost/config.hpp>
#include <boost/context/all.hpp>
#include <boost/context/execution_context.hpp>
#include <boost/cstdint.hpp>
#include <boost/exception/all.hpp>
#include <boost/utility.hpp>
@@ -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

View File

@@ -9,6 +9,7 @@
#include <boost/assert.hpp>
#include <boost/atomic.hpp>
#include <boost/config.hpp>
#include <boost/context/execution_context.hpp>
#include <boost/fiber/detail/config.hpp>
#include <boost/fiber/detail/fiber_base.hpp>
@@ -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();

View File

@@ -13,6 +13,7 @@
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/context/all.hpp>
#include <boost/context/execution_context.hpp>
#include <boost/move/move.hpp>
#include <boost/fiber/detail/config.hpp>
@@ -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)

View File

@@ -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;

View File

@@ -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