mirror of
https://github.com/boostorg/fiber.git
synced 2026-02-19 02:12:24 +00:00
Merge branch 'develop' of github.com:olk/boost-fiber into develop
This commit is contained in:
@@ -26,6 +26,7 @@
|
||||
#include <boost/intrusive/set.hpp>
|
||||
|
||||
#include <boost/fiber/detail/config.hpp>
|
||||
#include <boost/fiber/detail/data.hpp>
|
||||
#include <boost/fiber/detail/decay_copy.hpp>
|
||||
#include <boost/fiber/detail/fss.hpp>
|
||||
#include <boost/fiber/detail/spinlock.hpp>
|
||||
@@ -143,7 +144,8 @@ private:
|
||||
void * vp{ nullptr };
|
||||
detail::fss_cleanup_function::ptr_t cleanup_function{};
|
||||
|
||||
constexpr fss_data() noexcept = default;
|
||||
fss_data() noexcept {
|
||||
}
|
||||
|
||||
fss_data( void * vp_,
|
||||
detail::fss_cleanup_function::ptr_t const& fn) noexcept :
|
||||
@@ -157,65 +159,30 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
#if (BOOST_EXECUTION_CONTEXT==1)
|
||||
struct data_t {
|
||||
detail::spinlock_lock * lk{ nullptr };
|
||||
context * ctx{ nullptr };
|
||||
|
||||
constexpr data_t() noexcept = default;
|
||||
|
||||
explicit data_t( detail::spinlock_lock * lk_) noexcept :
|
||||
lk{ lk_ } {
|
||||
}
|
||||
|
||||
explicit data_t( context * ctx_) noexcept :
|
||||
ctx{ ctx_ } {
|
||||
}
|
||||
};
|
||||
#else
|
||||
struct data_t {
|
||||
detail::spinlock_lock * lk{ nullptr };
|
||||
context * ctx{ nullptr };
|
||||
context * from;
|
||||
|
||||
explicit data_t( context * from_) noexcept :
|
||||
from{ from_ } {
|
||||
}
|
||||
|
||||
explicit data_t( detail::spinlock_lock * lk_,
|
||||
context * from_) noexcept :
|
||||
lk{ lk_ },
|
||||
from{ from_ } {
|
||||
}
|
||||
|
||||
explicit data_t( context * ctx_,
|
||||
context * from_) noexcept :
|
||||
ctx{ ctx_ },
|
||||
from{ from_ } {
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef std::map< uintptr_t, fss_data > fss_data_t;
|
||||
|
||||
static thread_local context * active_;
|
||||
static thread_local context * active_;
|
||||
|
||||
#if ! defined(BOOST_FIBERS_NO_ATOMICS)
|
||||
std::atomic< std::size_t > use_count_{ 0 };
|
||||
std::atomic< int > flags_;
|
||||
std::atomic< std::size_t > use_count_{ 0 };
|
||||
std::atomic< int > flags_;
|
||||
#else
|
||||
std::size_t use_count_{ 0 };
|
||||
int flags_;
|
||||
std::size_t use_count_{ 0 };
|
||||
int flags_;
|
||||
#endif
|
||||
scheduler * scheduler_{ nullptr };
|
||||
#if (BOOST_EXECUTION_CONTEXT==1)
|
||||
boost::context::execution_context ctx_;
|
||||
#else
|
||||
boost::context::execution_context< detail::data_t * > ctx_;
|
||||
#endif
|
||||
scheduler * scheduler_{ nullptr };
|
||||
boost::context::execution_context ctx_;
|
||||
|
||||
void resume_( data_t &) noexcept;
|
||||
void resume_( detail::data_t &) noexcept;
|
||||
void set_ready_( context *) noexcept;
|
||||
|
||||
#if (BOOST_EXECUTION_CONTEXT==1)
|
||||
template< typename Fn, typename Tpl >
|
||||
void run_( Fn && fn_, Tpl && tpl_, data_t * dp) noexcept {
|
||||
void run_( Fn && fn_, Tpl && tpl_, detail::data_t * dp) noexcept {
|
||||
try {
|
||||
typename std::decay< Fn >::type fn = std::forward< Fn >( fn_);
|
||||
typename std::decay< Tpl >::type tpl = std::forward< Tpl >( tpl_);
|
||||
@@ -233,8 +200,8 @@ private:
|
||||
}
|
||||
#else
|
||||
template< typename Fn, typename Tpl >
|
||||
boost::context::execution_context
|
||||
run_( boost::context::execution_context ctx, Fn && fn_, Tpl && tpl_, data_t * dp) noexcept {
|
||||
boost::context::execution_context< detail::data_t * >
|
||||
run_( boost::context::execution_context< detail::data_t * > ctx, Fn && fn_, Tpl && tpl_, detail::data_t * dp) noexcept {
|
||||
try {
|
||||
typename std::decay< Fn >::type fn = std::forward< Fn >( fn_);
|
||||
typename std::decay< Tpl >::type tpl = std::forward< Tpl >( tpl_);
|
||||
@@ -279,7 +246,8 @@ public:
|
||||
context * impl_{ nullptr };
|
||||
|
||||
public:
|
||||
constexpr id() noexcept = default;
|
||||
id() noexcept {
|
||||
}
|
||||
|
||||
explicit id( context * impl) noexcept :
|
||||
impl_( impl) {
|
||||
@@ -355,7 +323,7 @@ public:
|
||||
detail::wrap(
|
||||
[this]( typename std::decay< Fn >::type & fn, typename std::decay< Tpl >::type & tpl,
|
||||
boost::context::execution_context & ctx, void * vp) mutable noexcept {
|
||||
run_( std::move( fn), std::move( tpl), static_cast< data_t * >( vp) );
|
||||
run_( std::move( fn), std::move( tpl), static_cast< detail::data_t * >( vp) );
|
||||
},
|
||||
std::forward< Fn >( fn),
|
||||
std::forward< Tpl >( tpl),
|
||||
@@ -365,7 +333,7 @@ public:
|
||||
ctx_{ std::allocator_arg, palloc, salloc,
|
||||
[this,fn=detail::decay_copy( std::forward< Fn >( fn) ),tpl=std::forward< Tpl >( tpl),
|
||||
ctx=boost::context::execution_context::current()] (void * vp) mutable noexcept {
|
||||
run_( std::move( fn), std::move( tpl), static_cast< data_t * >( vp) );
|
||||
run_( std::move( fn), std::move( tpl), static_cast< detail::data_t * >( vp) );
|
||||
}}
|
||||
# endif
|
||||
#else
|
||||
@@ -373,8 +341,8 @@ public:
|
||||
ctx_{ std::allocator_arg, palloc, salloc,
|
||||
detail::wrap(
|
||||
[this]( typename std::decay< Fn >::type & fn, typename std::decay< Tpl >::type & tpl,
|
||||
boost::context::execution_context ctx, void * vp) mutable noexcept {
|
||||
return run_( std::move( ctx), std::move( fn), std::move( tpl), static_cast< data_t * >( vp) );
|
||||
boost::context::execution_context< detail::data_t * > ctx, detail::data_t * dp) mutable noexcept {
|
||||
return run_( std::move( ctx), std::move( fn), std::move( tpl), dp);
|
||||
},
|
||||
std::forward< Fn >( fn),
|
||||
std::forward< Tpl >( tpl) )}
|
||||
@@ -382,8 +350,8 @@ public:
|
||||
# else
|
||||
ctx_{ std::allocator_arg, palloc, salloc,
|
||||
[this,fn=detail::decay_copy( std::forward< Fn >( fn) ),tpl=std::forward< Tpl >( tpl)]
|
||||
(boost::context::execution_context ctx, void * vp) mutable noexcept {
|
||||
return run_( std::move( ctx), std::move( fn), std::move( tpl), static_cast< data_t * >( vp) );
|
||||
(boost::context::execution_context< detail::data_t * > ctx, detail::data_t * dp) mutable noexcept {
|
||||
return run_( std::move( ctx), std::move( fn), std::move( tpl), dp);
|
||||
}}
|
||||
# endif
|
||||
#endif
|
||||
@@ -408,8 +376,8 @@ public:
|
||||
#if (BOOST_EXECUTION_CONTEXT==1)
|
||||
void set_terminated() noexcept;
|
||||
#else
|
||||
boost::context::execution_context suspend_with_cc() noexcept;
|
||||
boost::context::execution_context set_terminated() noexcept;
|
||||
boost::context::execution_context< detail::data_t * > suspend_with_cc() noexcept;
|
||||
boost::context::execution_context< detail::data_t * > set_terminated() noexcept;
|
||||
#endif
|
||||
void join();
|
||||
|
||||
@@ -539,11 +507,11 @@ public:
|
||||
// deallocates stack (execution_context is ref counted)
|
||||
ctx->~context();
|
||||
#else
|
||||
boost::context::execution_context cc( std::move( ctx->ctx_) );
|
||||
boost::context::execution_context< detail::data_t * > cc( std::move( ctx->ctx_) );
|
||||
// destruct context
|
||||
ctx->~context();
|
||||
// deallocated stack
|
||||
cc();
|
||||
cc( nullptr);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
71
include/boost/fiber/detail/data.hpp
Normal file
71
include/boost/fiber/detail/data.hpp
Normal file
@@ -0,0 +1,71 @@
|
||||
|
||||
// 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_DATA_H
|
||||
#define BOOST_FIBERS_DETAIL_DATA_H
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#include <boost/fiber/detail/config.hpp>
|
||||
#include <boost/fiber/detail/spinlock.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_ABI_HEADERS
|
||||
# include BOOST_ABI_PREFIX
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace fibers {
|
||||
|
||||
class context;
|
||||
|
||||
namespace detail {
|
||||
|
||||
#if (BOOST_EXECUTION_CONTEXT==1)
|
||||
struct data_t {
|
||||
spinlock_lock * lk{ nullptr };
|
||||
context * ctx{ nullptr };
|
||||
|
||||
constexpr data_t() noexcept = default;
|
||||
|
||||
explicit data_t( spinlock_lock * lk_) noexcept :
|
||||
lk{ lk_ } {
|
||||
}
|
||||
|
||||
explicit data_t( context * ctx_) noexcept :
|
||||
ctx{ ctx_ } {
|
||||
}
|
||||
};
|
||||
#else
|
||||
struct data_t {
|
||||
spinlock_lock * lk{ nullptr };
|
||||
context * ctx{ nullptr };
|
||||
context * from;
|
||||
|
||||
explicit data_t( context * from_) noexcept :
|
||||
from{ from_ } {
|
||||
}
|
||||
|
||||
explicit data_t( spinlock_lock * lk_,
|
||||
context * from_) noexcept :
|
||||
lk{ lk_ },
|
||||
from{ from_ } {
|
||||
}
|
||||
|
||||
explicit data_t( context * ctx_,
|
||||
context * from_) noexcept :
|
||||
ctx{ ctx_ },
|
||||
from{ from_ } {
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
}}}
|
||||
|
||||
#ifdef BOOST_HAS_ABI_HEADERS
|
||||
# include BOOST_ABI_SUFFIX
|
||||
#endif
|
||||
|
||||
#endif // BOOST_FIBERS_DETAIL_DATA_H
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <boost/context/execution_context.hpp>
|
||||
|
||||
#include <boost/fiber/detail/config.hpp>
|
||||
#include <boost/fiber/detail/data.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_ABI_HEADERS
|
||||
# include BOOST_ABI_PREFIX
|
||||
@@ -85,11 +86,11 @@ public:
|
||||
wrapper( wrapper && other) = default;
|
||||
wrapper & operator=( wrapper && other) = default;
|
||||
|
||||
boost::context::execution_context
|
||||
operator()( boost::context::execution_context ctx, void * vp) {
|
||||
boost::context::execution_context< data_t * >
|
||||
operator()( boost::context::execution_context< data_t * > ctx, data_t * dp) {
|
||||
return boost::context::detail::invoke(
|
||||
std::move( fn1_),
|
||||
fn2_, tpl_, std::move( ctx), vp);
|
||||
fn2_, tpl_, std::move( ctx), dp);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <boost/fiber/algorithm.hpp>
|
||||
#include <boost/fiber/context.hpp>
|
||||
#include <boost/fiber/detail/config.hpp>
|
||||
#include <boost/fiber/detail/data.hpp>
|
||||
#include <boost/fiber/detail/spinlock.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_ABI_HEADERS
|
||||
@@ -109,9 +110,9 @@ public:
|
||||
|
||||
void set_terminated( context *) noexcept;
|
||||
#else
|
||||
boost::context::execution_context dispatch() noexcept;
|
||||
boost::context::execution_context< detail::data_t * > dispatch() noexcept;
|
||||
|
||||
boost::context::execution_context set_terminated( context *) noexcept;
|
||||
boost::context::execution_context< detail::data_t * > set_terminated( context *) noexcept;
|
||||
#endif
|
||||
|
||||
void yield( context *) noexcept;
|
||||
|
||||
@@ -150,8 +150,8 @@ context::reset_active() noexcept {
|
||||
|
||||
#if (BOOST_EXECUTION_CONTEXT==1)
|
||||
void
|
||||
context::resume_( data_t & d) noexcept {
|
||||
data_t * dp = static_cast< data_t * >( ctx_( & d) );
|
||||
context::resume_( detail::data_t & d) noexcept {
|
||||
detail::data_t * dp = static_cast< detail::data_t * >( ctx_( & d) );
|
||||
if ( nullptr != dp->lk) {
|
||||
dp->lk->unlock();
|
||||
} else if ( nullptr != dp->ctx) {
|
||||
@@ -160,9 +160,9 @@ context::resume_( data_t & d) noexcept {
|
||||
}
|
||||
#else
|
||||
void
|
||||
context::resume_( data_t & d) noexcept {
|
||||
context::resume_( detail::data_t & d) noexcept {
|
||||
auto result = ctx_( & d);
|
||||
data_t * dp( static_cast< data_t * >( std::get< 1 >( result) ) );
|
||||
detail::data_t * dp( std::get< 1 >( result) );
|
||||
if ( nullptr != dp) {
|
||||
dp->from->ctx_ = std::move( std::get< 0 >( result) );
|
||||
if ( nullptr != dp->lk) {
|
||||
@@ -186,7 +186,7 @@ context::context( main_context_t) noexcept :
|
||||
#if (BOOST_EXECUTION_CONTEXT==1)
|
||||
ctx_{ boost::context::execution_context::current() } {
|
||||
#else
|
||||
ctx_() {
|
||||
ctx_{} {
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -197,7 +197,7 @@ context::context( dispatcher_context_t, boost::context::preallocated const& pall
|
||||
#if (BOOST_EXECUTION_CONTEXT==1)
|
||||
ctx_{ std::allocator_arg, palloc, salloc,
|
||||
[this,sched](void * vp) noexcept {
|
||||
data_t * dp = static_cast< data_t * >( vp);
|
||||
detail::data_t * dp = static_cast< detail::data_t * >( vp);
|
||||
if ( nullptr != dp->lk) {
|
||||
dp->lk->unlock();
|
||||
} else if ( nullptr != dp->ctx) {
|
||||
@@ -210,8 +210,7 @@ context::context( dispatcher_context_t, boost::context::preallocated const& pall
|
||||
}}
|
||||
#else
|
||||
ctx_{ std::allocator_arg, palloc, salloc,
|
||||
[this,sched](boost::context::execution_context ctx, void * vp) noexcept {
|
||||
data_t * dp = static_cast< data_t * >( vp);
|
||||
[this,sched](boost::context::execution_context< detail::data_t * > ctx, detail::data_t * dp) noexcept {
|
||||
// update execution_context of calling fiber
|
||||
dp->from->ctx_ = std::move( ctx);
|
||||
if ( nullptr != dp->lk) {
|
||||
@@ -250,9 +249,9 @@ context::resume() noexcept {
|
||||
// prev will point to previous active context
|
||||
std::swap( active_, prev);
|
||||
#if (BOOST_EXECUTION_CONTEXT==1)
|
||||
data_t d{};
|
||||
detail::data_t d{};
|
||||
#else
|
||||
data_t d{ prev };
|
||||
detail::data_t d{ prev };
|
||||
#endif
|
||||
resume_( d);
|
||||
}
|
||||
@@ -264,9 +263,9 @@ context::resume( detail::spinlock_lock & lk) noexcept {
|
||||
// prev will point to previous active context
|
||||
std::swap( active_, prev);
|
||||
#if (BOOST_EXECUTION_CONTEXT==1)
|
||||
data_t d{ & lk };
|
||||
detail::data_t d{ & lk };
|
||||
#else
|
||||
data_t d{ & lk, prev };
|
||||
detail::data_t d{ & lk, prev };
|
||||
#endif
|
||||
resume_( d);
|
||||
}
|
||||
@@ -278,9 +277,9 @@ context::resume( context * ready_ctx) noexcept {
|
||||
// prev will point to previous active context
|
||||
std::swap( active_, prev);
|
||||
#if (BOOST_EXECUTION_CONTEXT==1)
|
||||
data_t d{ ready_ctx };
|
||||
detail::data_t d{ ready_ctx };
|
||||
#else
|
||||
data_t d{ ready_ctx, prev };
|
||||
detail::data_t d{ ready_ctx, prev };
|
||||
#endif
|
||||
resume_( d);
|
||||
}
|
||||
@@ -328,13 +327,13 @@ context::yield() noexcept {
|
||||
}
|
||||
|
||||
#if (BOOST_EXECUTION_CONTEXT>1)
|
||||
boost::context::execution_context
|
||||
boost::context::execution_context< detail::data_t * >
|
||||
context::suspend_with_cc() noexcept {
|
||||
context * prev = this;
|
||||
// active_ will point to `this`
|
||||
// prev will point to previous active context
|
||||
std::swap( active_, prev);
|
||||
data_t d{ prev };
|
||||
detail::data_t d{ prev };
|
||||
// context switch
|
||||
return std::move( std::get< 0 >( ctx_( & d) ) );
|
||||
}
|
||||
@@ -343,7 +342,7 @@ context::suspend_with_cc() noexcept {
|
||||
#if (BOOST_EXECUTION_CONTEXT==1)
|
||||
void
|
||||
#else
|
||||
boost::context::execution_context
|
||||
boost::context::execution_context< detail::data_t * >
|
||||
#endif
|
||||
context::set_terminated() noexcept {
|
||||
// protect for concurrent access
|
||||
|
||||
@@ -129,7 +129,7 @@ scheduler::~scheduler() {
|
||||
void
|
||||
scheduler::dispatch() noexcept {
|
||||
#else
|
||||
boost::context::execution_context
|
||||
boost::context::execution_context< detail::data_t * >
|
||||
scheduler::dispatch() noexcept {
|
||||
#endif
|
||||
BOOST_ASSERT( context::active() == dispatcher_ctx_);
|
||||
@@ -246,7 +246,7 @@ scheduler::set_remote_ready( context * ctx) noexcept {
|
||||
void
|
||||
scheduler::set_terminated( context * active_ctx) noexcept {
|
||||
#else
|
||||
boost::context::execution_context
|
||||
boost::context::execution_context< detail::data_t * >
|
||||
scheduler::set_terminated( context * active_ctx) noexcept {
|
||||
#endif
|
||||
BOOST_ASSERT( nullptr != active_ctx);
|
||||
|
||||
Reference in New Issue
Block a user