summaryrefslogtreecommitdiff
path: root/boost/coroutine2/detail
diff options
context:
space:
mode:
Diffstat (limited to 'boost/coroutine2/detail')
-rw-r--r--boost/coroutine2/detail/config.hpp12
-rw-r--r--boost/coroutine2/detail/pull_control_block.hpp33
-rw-r--r--boost/coroutine2/detail/pull_control_block.ipp221
-rw-r--r--boost/coroutine2/detail/pull_coroutine.hpp12
-rw-r--r--boost/coroutine2/detail/pull_coroutine.ipp15
-rw-r--r--boost/coroutine2/detail/push_control_block.hpp17
-rw-r--r--boost/coroutine2/detail/push_control_block.ipp212
-rw-r--r--boost/coroutine2/detail/push_coroutine.ipp7
8 files changed, 285 insertions, 244 deletions
diff --git a/boost/coroutine2/detail/config.hpp b/boost/coroutine2/detail/config.hpp
index c439ecc0ea..cfb95846a5 100644
--- a/boost/coroutine2/detail/config.hpp
+++ b/boost/coroutine2/detail/config.hpp
@@ -36,16 +36,4 @@
# include <boost/config/auto_link.hpp>
#endif
-#if defined(BOOST_USE_SEGMENTED_STACKS)
-# if ! ( (defined(__GNUC__) && __GNUC__ > 3 && __GNUC_MINOR__ > 6) || \
- (defined(__clang__) && __clang_major__ > 2 && __clang_minor__ > 3) )
-# error "compiler does not support segmented_stack stacks"
-# endif
-# define BOOST_COROUTINES2_SEGMENTS 10
-#endif
-
-#if defined(BOOST_CONTEXT_NO_EXECUTION_CONTEXT)
-# error "execution_context from boost.context not supported"
-#endif
-
#endif // BOOST_COROUTINES2_DETAIL_CONFIG_H
diff --git a/boost/coroutine2/detail/pull_control_block.hpp b/boost/coroutine2/detail/pull_control_block.hpp
index 1abb34a0db..7009454c88 100644
--- a/boost/coroutine2/detail/pull_control_block.hpp
+++ b/boost/coroutine2/detail/pull_control_block.hpp
@@ -8,6 +8,7 @@
#define BOOST_COROUTINES2_DETAIL_PULL_CONTROL_BLOCK_HPP
#include <exception>
+#include <type_traits>
#include <boost/config.hpp>
#include <boost/context/execution_context.hpp>
@@ -22,17 +23,18 @@ namespace detail {
template< typename T >
struct pull_coroutine< T >::control_block {
- typename push_coroutine< T >::control_block * other;
- boost::context::execution_context caller;
- boost::context::execution_context callee;
- bool preserve_fpu;
- int state;
- std::exception_ptr except;
+ typename push_coroutine< T >::control_block * other;
+ boost::context::execution_context ctx;
+ bool preserve_fpu;
+ int state;
+ std::exception_ptr except;
+ bool bvalid;
+ typename std::aligned_storage< sizeof( T), alignof( T) >::type storage[1];
template< typename StackAllocator, typename Fn >
control_block( context::preallocated, StackAllocator, Fn &&, bool);
- explicit control_block( typename push_coroutine< T >::control_block *);
+ explicit control_block( typename push_coroutine< T >::control_block *, boost::context::execution_context const&);
~control_block();
@@ -41,22 +43,26 @@ struct pull_coroutine< T >::control_block {
void resume();
+ void set( T *);
+
+ T & get();
+
bool valid() const noexcept;
};
template< typename T >
struct pull_coroutine< T & >::control_block {
typename push_coroutine< T & >::control_block * other;
- boost::context::execution_context caller;
- boost::context::execution_context callee;
+ boost::context::execution_context ctx;
bool preserve_fpu;
int state;
std::exception_ptr except;
+ T * t;
template< typename StackAllocator, typename Fn >
control_block( context::preallocated, StackAllocator, Fn &&, bool);
- explicit control_block( typename push_coroutine< T & >::control_block *);
+ explicit control_block( typename push_coroutine< T & >::control_block *, boost::context::execution_context const&);
~control_block();
@@ -65,13 +71,14 @@ struct pull_coroutine< T & >::control_block {
void resume();
+ T & get();
+
bool valid() const noexcept;
};
struct pull_coroutine< void >::control_block {
push_coroutine< void >::control_block * other;
- boost::context::execution_context caller;
- boost::context::execution_context callee;
+ boost::context::execution_context ctx;
bool preserve_fpu;
int state;
std::exception_ptr except;
@@ -79,7 +86,7 @@ struct pull_coroutine< void >::control_block {
template< typename StackAllocator, typename Fn >
control_block( context::preallocated, StackAllocator, Fn &&, bool);
- explicit control_block( push_coroutine< void >::control_block *);
+ explicit control_block( push_coroutine< void >::control_block *, boost::context::execution_context const&);
~control_block();
diff --git a/boost/coroutine2/detail/pull_control_block.ipp b/boost/coroutine2/detail/pull_control_block.ipp
index fd806ecb21..536e5e6a94 100644
--- a/boost/coroutine2/detail/pull_control_block.ipp
+++ b/boost/coroutine2/detail/pull_control_block.ipp
@@ -8,6 +8,7 @@
#define BOOST_COROUTINES2_DETAIL_PULL_CONTROL_BLOCK_IPP
#include <exception>
+#include <memory>
#include <boost/assert.hpp>
#include <boost/config.hpp>
@@ -33,42 +34,46 @@ template< typename StackAllocator, typename Fn >
pull_coroutine< T >::control_block::control_block( context::preallocated palloc, StackAllocator salloc,
Fn && fn_, bool preserve_fpu_) :
other( nullptr),
- caller( boost::context::execution_context::current() ),
- callee( palloc, salloc,
- [=,fn=std::forward< Fn >( fn_)] () mutable -> decltype( auto) {
- // create synthesized push_coroutine< T >
- typename push_coroutine< T >::control_block synthesized_cb( this);
- push_coroutine< T > synthesized( & synthesized_cb);
- other = & synthesized_cb;
- try {
- // call coroutine-fn with synthesized push_coroutine as argument
- fn( synthesized);
- } catch ( forced_unwind const&) {
- // do nothing for unwinding exception
- } catch (...) {
- // store other exceptions in exception-pointer
- except = std::current_exception();
- }
- // set termination flags
- state |= static_cast< int >( state_t::complete);
- // jump back to caller
- caller( preserve_fpu);
- BOOST_ASSERT_MSG( false, "pull_coroutine is complete");
- }),
+ ctx( std::allocator_arg, palloc, salloc,
+ [=,fn=std::forward< Fn >( fn_),ctx=boost::context::execution_context::current()] (void *) mutable -> void {
+ // create synthesized push_coroutine< T >
+ typename push_coroutine< T >::control_block synthesized_cb( this, ctx);
+ push_coroutine< T > synthesized( & synthesized_cb);
+ other = & synthesized_cb;
+ try {
+ // call coroutine-fn with synthesized push_coroutine as argument
+ fn( synthesized);
+ } catch ( forced_unwind const&) {
+ // do nothing for unwinding exception
+ } catch (...) {
+ // store other exceptions in exception-pointer
+ except = std::current_exception();
+ }
+ // set termination flags
+ state |= static_cast< int >( state_t::complete);
+ // jump back to ctx
+ other->ctx( nullptr, preserve_fpu);
+ BOOST_ASSERT_MSG( false, "pull_coroutine is complete");
+ }),
preserve_fpu( preserve_fpu_),
state( static_cast< int >( state_t::unwind) ),
- except() {
- callee( preserve_fpu);
+ except(),
+ bvalid( false),
+ storage() {
+ // enter coroutine-fn in order to have first value available after ctor (of `*this`) returns
+ set( reinterpret_cast< T * >( ctx( nullptr, preserve_fpu) ) );
}
template< typename T >
-pull_coroutine< T >::control_block::control_block( typename push_coroutine< T >::control_block * cb) :
+pull_coroutine< T >::control_block::control_block( typename push_coroutine< T >::control_block * cb,
+ boost::context::execution_context const& ctx_) :
other( cb),
- caller( other->callee),
- callee( other->caller),
+ ctx( ctx_),
preserve_fpu( other->preserve_fpu),
state( 0),
- except() {
+ except(),
+ bvalid( false),
+ storage() {
}
template< typename T >
@@ -77,14 +82,19 @@ pull_coroutine< T >::control_block::~control_block() {
0 != ( state & static_cast< int >( state_t::unwind) ) ) {
// set early-exit flag
state |= static_cast< int >( state_t::early_exit);
- callee( preserve_fpu);
+ ctx( nullptr, preserve_fpu);
+ }
+ // destroy data if it set
+ if ( bvalid) {
+ reinterpret_cast< T const* >( storage)->~T();
}
}
template< typename T >
void
pull_coroutine< T >::control_block::resume() {
- callee( preserve_fpu);
+ other->ctx = boost::context::execution_context::current();
+ set( reinterpret_cast< T * >( ctx( nullptr, preserve_fpu) ) );
if ( except) {
std::rethrow_exception( except);
}
@@ -95,9 +105,30 @@ pull_coroutine< T >::control_block::resume() {
}
template< typename T >
+void
+pull_coroutine< T >::control_block::set( T * t) {
+ // destroy data if it set
+ if ( bvalid) {
+ reinterpret_cast< T const* >( storage)->~T();
+ }
+ if ( nullptr != t) {
+ new ( storage) T( std::move( * t) ); // FIXME: differrentiation between move/copy
+ bvalid = true;
+ } else {
+ bvalid = false;
+ }
+}
+
+template< typename T >
+T &
+pull_coroutine< T >::control_block::get() {
+ return * reinterpret_cast< T * >( storage);
+}
+
+template< typename T >
bool
pull_coroutine< T >::control_block::valid() const noexcept {
- return nullptr != other && nullptr != other->t && 0 == ( state & static_cast< int >( state_t::complete) );
+ return nullptr != other && 0 == ( state & static_cast< int >( state_t::complete) ) && bvalid;
}
@@ -108,42 +139,44 @@ template< typename StackAllocator, typename Fn >
pull_coroutine< T & >::control_block::control_block( context::preallocated palloc, StackAllocator salloc,
Fn && fn_, bool preserve_fpu_) :
other( nullptr),
- caller( boost::context::execution_context::current() ),
- callee( palloc, salloc,
- [=,fn=std::forward< Fn >( fn_)] () mutable -> decltype( auto) {
- // create synthesized push_coroutine< T >
- typename push_coroutine< T & >::control_block synthesized_cb( this);
- push_coroutine< T & > synthesized( & synthesized_cb);
- other = & synthesized_cb;
- try {
- // call coroutine-fn with synthesized push_coroutine as argument
- fn( synthesized);
- } catch ( forced_unwind const&) {
- // do nothing for unwinding exception
- } catch (...) {
- // store other exceptions in exception-pointer
- except = std::current_exception();
- }
- // set termination flags
- state |= static_cast< int >( state_t::complete);
- // jump back to caller
- caller( preserve_fpu);
- BOOST_ASSERT_MSG( false, "pull_coroutine is complete");
- }),
+ ctx( std::allocator_arg, palloc, salloc,
+ [=,fn=std::forward< Fn >( fn_),ctx=boost::context::execution_context::current()] (void *) mutable -> void {
+ // create synthesized push_coroutine< T >
+ typename push_coroutine< T & >::control_block synthesized_cb( this, ctx);
+ push_coroutine< T & > synthesized( & synthesized_cb);
+ other = & synthesized_cb;
+ try {
+ // call coroutine-fn with synthesized push_coroutine as argument
+ fn( synthesized);
+ } catch ( forced_unwind const&) {
+ // do nothing for unwinding exception
+ } catch (...) {
+ // store other exceptions in exception-pointer
+ except = std::current_exception();
+ }
+ // set termination flags
+ state |= static_cast< int >( state_t::complete);
+ // jump back to ctx
+ other->ctx( nullptr, preserve_fpu);
+ BOOST_ASSERT_MSG( false, "pull_coroutine is complete");
+ }),
preserve_fpu( preserve_fpu_),
state( static_cast< int >( state_t::unwind) ),
- except() {
- callee( preserve_fpu);
+ except(),
+ t( nullptr) {
+ // enter coroutine-fn in order to have first value available after ctor (of `*this`) returns
+ t = reinterpret_cast< T * >( ctx( nullptr, preserve_fpu) );
}
template< typename T >
-pull_coroutine< T & >::control_block::control_block( typename push_coroutine< T & >::control_block * cb) :
+pull_coroutine< T & >::control_block::control_block( typename push_coroutine< T & >::control_block * cb,
+ boost::context::execution_context const& ctx_) :
other( cb),
- caller( other->callee),
- callee( other->caller),
+ ctx( ctx_),
preserve_fpu( other->preserve_fpu),
state( 0),
- except() {
+ except(),
+ t( nullptr) {
}
template< typename T >
@@ -152,14 +185,15 @@ pull_coroutine< T & >::control_block::~control_block() {
0 != ( state & static_cast< int >( state_t::unwind) ) ) {
// set early-exit flag
state |= static_cast< int >( state_t::early_exit);
- callee( preserve_fpu);
+ ctx( nullptr, preserve_fpu);
}
}
template< typename T >
void
pull_coroutine< T & >::control_block::resume() {
- callee( preserve_fpu);
+ other->ctx = boost::context::execution_context::current();
+ t = reinterpret_cast< T * >( ctx( nullptr, preserve_fpu) );
if ( except) {
std::rethrow_exception( except);
}
@@ -170,9 +204,15 @@ pull_coroutine< T & >::control_block::resume() {
}
template< typename T >
+T &
+pull_coroutine< T & >::control_block::get() {
+ return * reinterpret_cast< T * >( t);
+}
+
+template< typename T >
bool
pull_coroutine< T & >::control_block::valid() const noexcept {
- return nullptr != other && nullptr != other->t && 0 == ( state & static_cast< int >( state_t::complete) );
+ return nullptr != other && 0 == ( state & static_cast< int >( state_t::complete) ) && nullptr != t;
}
@@ -182,39 +222,39 @@ template< typename StackAllocator, typename Fn >
pull_coroutine< void >::control_block::control_block( context::preallocated palloc, StackAllocator salloc,
Fn && fn_, bool preserve_fpu_) :
other( nullptr),
- caller( boost::context::execution_context::current() ),
- callee( palloc, salloc,
- [=,fn=std::forward< Fn >( fn_)] () mutable -> decltype( auto) {
- // create synthesized push_coroutine< T >
- typename push_coroutine< void >::control_block synthesized_cb( this);
- push_coroutine< void > synthesized( & synthesized_cb);
- other = & synthesized_cb;
- try {
- // call coroutine-fn with synthesized push_coroutine as argument
- fn( synthesized);
- } catch ( forced_unwind const&) {
- // do nothing for unwinding exception
- } catch (...) {
- // store other exceptions in exception-pointer
- except = std::current_exception();
- }
- // set termination flags
- state |= static_cast< int >( state_t::complete);
- // jump back to caller
- caller( preserve_fpu);
- BOOST_ASSERT_MSG( false, "pull_coroutine is complete");
- }),
+ ctx( std::allocator_arg, palloc, salloc,
+ [=,fn=std::forward< Fn >( fn_),ctx=boost::context::execution_context::current()] (void *) mutable -> void {
+ // create synthesized push_coroutine< T >
+ typename push_coroutine< void >::control_block synthesized_cb( this, ctx);
+ push_coroutine< void > synthesized( & synthesized_cb);
+ other = & synthesized_cb;
+ try {
+ // call coroutine-fn with synthesized push_coroutine as argument
+ fn( synthesized);
+ } catch ( forced_unwind const&) {
+ // do nothing for unwinding exception
+ } catch (...) {
+ // store other exceptions in exception-pointer
+ except = std::current_exception();
+ }
+ // set termination flags
+ state |= static_cast< int >( state_t::complete);
+ // jump back to ctx
+ other->ctx( nullptr, preserve_fpu);
+ BOOST_ASSERT_MSG( false, "pull_coroutine is complete");
+ }),
preserve_fpu( preserve_fpu_),
state( static_cast< int >( state_t::unwind) ),
except() {
- callee( preserve_fpu);
+ // enter coroutine-fn in order to have first value available after ctor returns
+ ctx( nullptr, preserve_fpu);
}
inline
-pull_coroutine< void >::control_block::control_block( push_coroutine< void >::control_block * cb) :
+pull_coroutine< void >::control_block::control_block( push_coroutine< void >::control_block * cb,
+ boost::context::execution_context const& ctx_) :
other( cb),
- caller( other->callee),
- callee( other->caller),
+ ctx( ctx_),
preserve_fpu( other->preserve_fpu),
state( 0),
except() {
@@ -226,14 +266,15 @@ pull_coroutine< void >::control_block::~control_block() {
0 != ( state & static_cast< int >( state_t::unwind) ) ) {
// set early-exit flag
state |= static_cast< int >( state_t::early_exit);
- callee( preserve_fpu);
+ ctx( nullptr, preserve_fpu);
}
}
inline
void
pull_coroutine< void >::control_block::resume() {
- callee( preserve_fpu);
+ other->ctx = boost::context::execution_context::current();
+ ctx( nullptr, preserve_fpu);
if ( except) {
std::rethrow_exception( except);
}
diff --git a/boost/coroutine2/detail/pull_coroutine.hpp b/boost/coroutine2/detail/pull_coroutine.hpp
index ff76bd3aac..c78750442e 100644
--- a/boost/coroutine2/detail/pull_coroutine.hpp
+++ b/boost/coroutine2/detail/pull_coroutine.hpp
@@ -66,7 +66,7 @@ public:
bool operator!() const noexcept;
- T get() const noexcept;
+ T get();
class iterator : public std::iterator< std::input_iterator_tag, typename std::remove_reference< T >::type > {
private:
@@ -126,11 +126,11 @@ public:
iterator operator++( int) = delete;
reference_t operator*() const {
- return * c_->cb_->other->t;
+ return c_->cb_->get();
}
pointer_t operator->() const {
- return c_->cb_->other->t;
+ return std::addressof( c_->cb_->get() );
}
};
@@ -179,7 +179,7 @@ public:
bool operator!() const noexcept;
- T & get() const noexcept;
+ T & get();
class iterator : public std::iterator< std::input_iterator_tag, typename std::remove_reference< T >::type > {
private:
@@ -239,11 +239,11 @@ public:
iterator operator++( int) = delete;
reference_t operator*() const {
- return * c_->cb_->other->t;
+ return c_->cb_->get();
}
pointer_t operator->() const {
- return c_->cb_->other->t;
+ return std::addressof( c_->cb_->get() );
}
};
diff --git a/boost/coroutine2/detail/pull_coroutine.ipp b/boost/coroutine2/detail/pull_coroutine.ipp
index f59bb3cb5f..2e37ef2a98 100644
--- a/boost/coroutine2/detail/pull_coroutine.ipp
+++ b/boost/coroutine2/detail/pull_coroutine.ipp
@@ -19,6 +19,7 @@
#include <boost/coroutine2/detail/config.hpp>
#include <boost/coroutine2/fixedsize_stack.hpp>
+#include <boost/coroutine2/segmented_stack.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
@@ -44,7 +45,7 @@ pull_coroutine< T >::has_result_() const {
template< typename T >
template< typename Fn >
pull_coroutine< T >::pull_coroutine( Fn && fn, bool preserve_fpu) :
- pull_coroutine( fixedsize_stack(), std::forward< Fn >( fn), preserve_fpu) {
+ pull_coroutine( default_stack(), std::forward< Fn >( fn), preserve_fpu) {
}
template< typename T >
@@ -106,8 +107,8 @@ pull_coroutine< T >::operator!() const noexcept {
template< typename T >
T
-pull_coroutine< T >::get() const noexcept {
- return std::move( * cb_->other->t);
+pull_coroutine< T >::get() {
+ return std::move( cb_->get() );
}
@@ -127,7 +128,7 @@ pull_coroutine< T & >::has_result_() const {
template< typename T >
template< typename Fn >
pull_coroutine< T & >::pull_coroutine( Fn && fn, bool preserve_fpu) :
- pull_coroutine( fixedsize_stack(), std::forward< Fn >( fn), preserve_fpu) {
+ pull_coroutine( default_stack(), std::forward< Fn >( fn), preserve_fpu) {
}
template< typename T >
@@ -189,8 +190,8 @@ pull_coroutine< T & >::operator!() const noexcept {
template< typename T >
T &
-pull_coroutine< T & >::get() const noexcept {
- return * cb_->other->t;
+pull_coroutine< T & >::get() {
+ return cb_->get();
}
@@ -203,7 +204,7 @@ pull_coroutine< void >::pull_coroutine( control_block * cb) :
template< typename Fn >
pull_coroutine< void >::pull_coroutine( Fn && fn, bool preserve_fpu) :
- pull_coroutine( fixedsize_stack(), std::forward< Fn >( fn), preserve_fpu) {
+ pull_coroutine( default_stack(), std::forward< Fn >( fn), preserve_fpu) {
}
template< typename StackAllocator, typename Fn >
diff --git a/boost/coroutine2/detail/push_control_block.hpp b/boost/coroutine2/detail/push_control_block.hpp
index e6c86ffd81..03aa9125eb 100644
--- a/boost/coroutine2/detail/push_control_block.hpp
+++ b/boost/coroutine2/detail/push_control_block.hpp
@@ -23,17 +23,15 @@ namespace detail {
template< typename T >
struct push_coroutine< T >::control_block {
typename pull_coroutine< T >::control_block * other;
- boost::context::execution_context caller;
- boost::context::execution_context callee;
+ boost::context::execution_context ctx;
bool preserve_fpu;
int state;
std::exception_ptr except;
- T * t;
template< typename StackAllocator, typename Fn >
control_block( context::preallocated, StackAllocator, Fn &&, bool);
- explicit control_block( typename pull_coroutine< T >::control_block *);
+ explicit control_block( typename pull_coroutine< T >::control_block *, boost::context::execution_context const&);
~control_block();
@@ -50,17 +48,15 @@ struct push_coroutine< T >::control_block {
template< typename T >
struct push_coroutine< T & >::control_block {
typename pull_coroutine< T & >::control_block * other;
- boost::context::execution_context caller;
- boost::context::execution_context callee;
+ boost::context::execution_context ctx;
bool preserve_fpu;
int state;
std::exception_ptr except;
- T * t;
template< typename StackAllocator, typename Fn >
control_block( context::preallocated, StackAllocator, Fn &&, bool);
- explicit control_block( typename pull_coroutine< T & >::control_block *);
+ explicit control_block( typename pull_coroutine< T & >::control_block *, boost::context::execution_context const&);
~control_block();
@@ -74,8 +70,7 @@ struct push_coroutine< T & >::control_block {
struct push_coroutine< void >::control_block {
pull_coroutine< void >::control_block * other;
- boost::context::execution_context caller;
- boost::context::execution_context callee;
+ boost::context::execution_context ctx;
bool preserve_fpu;
int state;
std::exception_ptr except;
@@ -83,7 +78,7 @@ struct push_coroutine< void >::control_block {
template< typename StackAllocator, typename Fn >
control_block( context::preallocated, StackAllocator, Fn &&, bool);
- explicit control_block( pull_coroutine< void >::control_block *);
+ explicit control_block( pull_coroutine< void >::control_block *, boost::context::execution_context const&);
~control_block();
diff --git a/boost/coroutine2/detail/push_control_block.ipp b/boost/coroutine2/detail/push_control_block.ipp
index ebef5092b5..ce6776f600 100644
--- a/boost/coroutine2/detail/push_control_block.ipp
+++ b/boost/coroutine2/detail/push_control_block.ipp
@@ -9,6 +9,7 @@
#include <algorithm>
#include <exception>
+#include <memory>
#include <boost/assert.hpp>
#include <boost/config.hpp>
@@ -34,42 +35,46 @@ template< typename StackAllocator, typename Fn >
push_coroutine< T >::control_block::control_block( context::preallocated palloc, StackAllocator salloc,
Fn && fn_, bool preserve_fpu_) :
other( nullptr),
- caller( boost::context::execution_context::current() ),
- callee( palloc, salloc,
- [=,fn=std::forward< Fn >( fn_)] () mutable -> decltype( auto) {
- // create synthesized pull_coroutine< T >
- typename pull_coroutine< T >::control_block synthesized_cb( this);
- pull_coroutine< T > synthesized( & synthesized_cb);
- other = & synthesized_cb;
- try {
- // call coroutine-fn with synthesized pull_coroutine as argument
- fn( synthesized);
- } catch ( forced_unwind const&) {
- // do nothing for unwinding exception
- } catch (...) {
- // store other exceptions in exception-pointer
- except = std::current_exception();
- }
- // set termination flags
- state |= static_cast< int >( state_t::complete);
- caller( preserve_fpu);
- BOOST_ASSERT_MSG( false, "push_coroutine is complete");
- }),
+ ctx( std::allocator_arg, palloc, salloc,
+ [=,fn=std::forward< Fn >( fn_),ctx=boost::context::execution_context::current()] (void *) mutable -> void {
+ // create synthesized pull_coroutine< T >
+ typename pull_coroutine< T >::control_block synthesized_cb( this, ctx);
+ pull_coroutine< T > synthesized( & synthesized_cb);
+ other = & synthesized_cb;
+ // jump back to ctor
+ T * t = reinterpret_cast< T * >( ctx( nullptr, preserve_fpu) );
+ // set transferred value
+ synthesized_cb.set( t);
+ try {
+ // call coroutine-fn with synthesized pull_coroutine as argument
+ fn( synthesized);
+ } catch ( forced_unwind const&) {
+ // do nothing for unwinding exception
+ } catch (...) {
+ // store other exceptions in exception-pointer
+ except = std::current_exception();
+ }
+ // set termination flags
+ state |= static_cast< int >( state_t::complete);
+ // jump back to ctx
+ other->ctx( nullptr, preserve_fpu);
+ BOOST_ASSERT_MSG( false, "push_coroutine is complete");
+ }),
preserve_fpu( preserve_fpu_),
state( static_cast< int >( state_t::unwind) ),
- except(),
- t( nullptr) {
+ except() {
+ // enter coroutine-fn in order to get other set
+ ctx( nullptr, preserve_fpu);
}
template< typename T >
-push_coroutine< T >::control_block::control_block( typename pull_coroutine< T >::control_block * cb) :
+push_coroutine< T >::control_block::control_block( typename pull_coroutine< T >::control_block * cb,
+ boost::context::execution_context const& ctx_) :
other( cb),
- caller( other->callee),
- callee( other->caller),
+ ctx( ctx_),
preserve_fpu( other->preserve_fpu),
state( 0),
- except(),
- t( nullptr) {
+ except() {
}
template< typename T >
@@ -78,19 +83,16 @@ push_coroutine< T >::control_block::~control_block() {
0 != ( state & static_cast< int >( state_t::unwind) ) ) {
// set early-exit flag
state |= static_cast< int >( state_t::early_exit);
- callee( preserve_fpu);
+ ctx( nullptr, preserve_fpu);
}
}
template< typename T >
void
-push_coroutine< T >::control_block::resume( T const& t_) {
- // store data on this stack
- // pass an pointer (address of tmp) to other context
- T tmp( t_);
- t = & tmp;
- callee( preserve_fpu);
- t = nullptr;
+push_coroutine< T >::control_block::resume( T const& t) {
+ other->ctx = boost::context::execution_context::current();
+ // pass an pointer to other context
+ ctx( const_cast< T * >( & t), preserve_fpu);
if ( except) {
std::rethrow_exception( except);
}
@@ -102,13 +104,10 @@ push_coroutine< T >::control_block::resume( T const& t_) {
template< typename T >
void
-push_coroutine< T >::control_block::resume( T && t_) {
- // store data on this stack
- // pass an pointer (address of tmp) to other context
- T tmp( std::move( t_) );
- t = & tmp;
- callee( preserve_fpu);
- t = nullptr;
+push_coroutine< T >::control_block::resume( T && t) {
+ other->ctx = boost::context::execution_context::current();
+ // pass an pointer to other context
+ ctx( std::addressof( t), preserve_fpu);
if ( except) {
std::rethrow_exception( except);
}
@@ -132,42 +131,46 @@ template< typename StackAllocator, typename Fn >
push_coroutine< T & >::control_block::control_block( context::preallocated palloc, StackAllocator salloc,
Fn && fn_, bool preserve_fpu_) :
other( nullptr),
- caller( boost::context::execution_context::current() ),
- callee( palloc, salloc,
- [=,fn=std::forward< Fn >( fn_)] () mutable -> decltype( auto) {
- // create synthesized pull_coroutine< T >
- typename pull_coroutine< T & >::control_block synthesized_cb( this);
- pull_coroutine< T & > synthesized( & synthesized_cb);
- other = & synthesized_cb;
- try {
- // call coroutine-fn with synthesized pull_coroutine as argument
- fn( synthesized);
- } catch ( forced_unwind const&) {
- // do nothing for unwinding exception
- } catch (...) {
- // store other exceptions in exception-pointer
- except = std::current_exception();
- }
- // set termination flags
- state |= static_cast< int >( state_t::complete);
- caller( preserve_fpu);
- BOOST_ASSERT_MSG( false, "push_coroutine is complete");
- }),
+ ctx( std::allocator_arg, palloc, salloc,
+ [=,fn=std::forward< Fn >( fn_),ctx=boost::context::execution_context::current()] (void *) mutable -> void {
+ // create synthesized pull_coroutine< T >
+ typename pull_coroutine< T & >::control_block synthesized_cb( this, ctx);
+ pull_coroutine< T & > synthesized( & synthesized_cb);
+ other = & synthesized_cb;
+ // jump back to ctor
+ T * t = reinterpret_cast< T * >( ctx( nullptr, preserve_fpu) );
+ // set transferred value
+ synthesized_cb.t = t;
+ try {
+ // call coroutine-fn with synthesized pull_coroutine as argument
+ fn( synthesized);
+ } catch ( forced_unwind const&) {
+ // do nothing for unwinding exception
+ } catch (...) {
+ // store other exceptions in exception-pointer
+ except = std::current_exception();
+ }
+ // set termination flags
+ state |= static_cast< int >( state_t::complete);
+ // jump back to ctx
+ other->ctx( nullptr, preserve_fpu);
+ BOOST_ASSERT_MSG( false, "push_coroutine is complete");
+ }),
preserve_fpu( preserve_fpu_),
state( static_cast< int >( state_t::unwind) ),
- except(),
- t( nullptr) {
+ except() {
+ // enter coroutine-fn in order to get other set
+ ctx( nullptr, preserve_fpu);
}
template< typename T >
-push_coroutine< T & >::control_block::control_block( typename pull_coroutine< T & >::control_block * cb) :
+push_coroutine< T & >::control_block::control_block( typename pull_coroutine< T & >::control_block * cb,
+ boost::context::execution_context const& ctx_) :
other( cb),
- caller( other->callee),
- callee( other->caller),
+ ctx( ctx_),
preserve_fpu( other->preserve_fpu),
state( 0),
- except(),
- t( nullptr) {
+ except() {
}
template< typename T >
@@ -176,16 +179,16 @@ push_coroutine< T & >::control_block::~control_block() {
0 != ( state & static_cast< int >( state_t::unwind) ) ) {
// set early-exit flag
state |= static_cast< int >( state_t::early_exit);
- callee( preserve_fpu);
+ ctx( nullptr, preserve_fpu);
}
}
template< typename T >
void
-push_coroutine< T & >::control_block::resume( T & t_) {
- t = & t_;
- callee( preserve_fpu);
- t = nullptr;
+push_coroutine< T & >::control_block::resume( T & t) {
+ other->ctx = boost::context::execution_context::current();
+ // pass an pointer to other context
+ ctx( const_cast< typename std::remove_const< T >::type * >( std::addressof( t) ), preserve_fpu);
if ( except) {
std::rethrow_exception( except);
}
@@ -207,37 +210,41 @@ push_coroutine< T & >::control_block::valid() const noexcept {
template< typename StackAllocator, typename Fn >
push_coroutine< void >::control_block::control_block( context::preallocated palloc, StackAllocator salloc, Fn && fn_, bool preserve_fpu_) :
other( nullptr),
- caller( boost::context::execution_context::current() ),
- callee( palloc, salloc,
- [=,fn=std::forward< Fn >( fn_)] () mutable -> decltype( auto) {
- // create synthesized pull_coroutine< T >
- typename pull_coroutine< void >::control_block synthesized_cb( this);
- pull_coroutine< void > synthesized( & synthesized_cb);
- other = & synthesized_cb;
- try {
- // call coroutine-fn with synthesized pull_coroutine as argument
- fn( synthesized);
- } catch ( forced_unwind const&) {
- // do nothing for unwinding exception
- } catch (...) {
- // store other exceptions in exception-pointer
- except = std::current_exception();
- }
- // set termination flags
- state |= static_cast< int >( state_t::complete);
- caller( preserve_fpu);
- BOOST_ASSERT_MSG( false, "push_coroutine is complete");
- }),
+ ctx( std::allocator_arg, palloc, salloc,
+ [=,fn=std::forward< Fn >( fn_),ctx=boost::context::execution_context::current()] (void *) mutable -> void {
+ // create synthesized pull_coroutine< T >
+ typename pull_coroutine< void >::control_block synthesized_cb( this, ctx);
+ pull_coroutine< void > synthesized( & synthesized_cb);
+ other = & synthesized_cb;
+ // jump back to ctor
+ ctx( nullptr, preserve_fpu);
+ try {
+ // call coroutine-fn with synthesized pull_coroutine as argument
+ fn( synthesized);
+ } catch ( forced_unwind const&) {
+ // do nothing for unwinding exception
+ } catch (...) {
+ // store other exceptions in exception-pointer
+ except = std::current_exception();
+ }
+ // set termination flags
+ state |= static_cast< int >( state_t::complete);
+ // jump back to ctx
+ other->ctx( nullptr, preserve_fpu);
+ BOOST_ASSERT_MSG( false, "push_coroutine is complete");
+ }),
preserve_fpu( preserve_fpu_),
state( static_cast< int >( state_t::unwind) ),
except() {
+ // enter coroutine-fn in order to get other set
+ ctx( nullptr, preserve_fpu);
}
inline
-push_coroutine< void >::control_block::control_block( pull_coroutine< void >::control_block * cb) :
+push_coroutine< void >::control_block::control_block( pull_coroutine< void >::control_block * cb,
+ boost::context::execution_context const& ctx_) :
other( cb),
- caller( other->callee),
- callee( other->caller),
+ ctx( ctx_),
preserve_fpu( other->preserve_fpu),
state( 0),
except() {
@@ -249,14 +256,15 @@ push_coroutine< void >::control_block::~control_block() {
0 != ( state & static_cast< int >( state_t::unwind) ) ) {
// set early-exit flag
state |= static_cast< int >( state_t::early_exit);
- callee( preserve_fpu);
+ ctx( nullptr, preserve_fpu);
}
}
inline
void
push_coroutine< void >::control_block::resume() {
- callee( preserve_fpu);
+ other->ctx = boost::context::execution_context::current();
+ ctx( nullptr, preserve_fpu);
if ( except) {
std::rethrow_exception( except);
}
diff --git a/boost/coroutine2/detail/push_coroutine.ipp b/boost/coroutine2/detail/push_coroutine.ipp
index 4617e73aac..5f4817802a 100644
--- a/boost/coroutine2/detail/push_coroutine.ipp
+++ b/boost/coroutine2/detail/push_coroutine.ipp
@@ -18,6 +18,7 @@
#include <boost/coroutine2/detail/config.hpp>
#include <boost/coroutine2/fixedsize_stack.hpp>
+#include <boost/coroutine2/segmented_stack.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
@@ -37,7 +38,7 @@ push_coroutine< T >::push_coroutine( control_block * cb) :
template< typename T >
template< typename Fn >
push_coroutine< T >::push_coroutine( Fn && fn, bool preserve_fpu) :
- push_coroutine( fixedsize_stack(), std::forward< Fn >( fn), preserve_fpu) {
+ push_coroutine( default_stack(), std::forward< Fn >( fn), preserve_fpu) {
}
template< typename T >
@@ -115,7 +116,7 @@ push_coroutine< T & >::push_coroutine( control_block * cb) :
template< typename T >
template< typename Fn >
push_coroutine< T & >::push_coroutine( Fn && fn, bool preserve_fpu) :
- push_coroutine( fixedsize_stack(), std::forward< Fn >( fn), preserve_fpu) {
+ push_coroutine( default_stack(), std::forward< Fn >( fn), preserve_fpu) {
}
template< typename T >
@@ -185,7 +186,7 @@ push_coroutine< void >::push_coroutine( control_block * cb) :
template< typename Fn >
push_coroutine< void >::push_coroutine( Fn && fn, bool preserve_fpu) :
- push_coroutine( fixedsize_stack(), std::forward< Fn >( fn), preserve_fpu) {
+ push_coroutine( default_stack(), std::forward< Fn >( fn), preserve_fpu) {
}
template< typename StackAllocator, typename Fn >