diff --git a/example/fibonacci.cpp b/example/fibonacci.cpp index 2cca0c1..547342c 100644 --- a/example/fibonacci.cpp +++ b/example/fibonacci.cpp @@ -9,26 +9,22 @@ #include -int main() -{ +int main() { boost::coroutines2::coroutine< int >::pull_type source( - [&]( boost::coroutines2::coroutine< int >::push_type & sink) { + []( boost::coroutines2::coroutine< int >::push_type & sink) { int first = 1, second = 1; sink( first); sink( second); - for ( int i = 0; i < 8; ++i) - { + for ( int i = 0; i < 8; ++i) { int third = first + second; first = second; second = third; sink( third); } }); - - for ( auto i : source) + for ( auto i : source) { std::cout << i << " "; - + } std::cout << "\nDone" << std::endl; - return EXIT_SUCCESS; } diff --git a/example/layout.cpp b/example/layout.cpp index 96813e9..e8f69e0 100644 --- a/example/layout.cpp +++ b/example/layout.cpp @@ -21,13 +21,11 @@ struct FinalEOL{ int main(int argc,char* argv[]){ using std::begin; using std::end; - std::vector words{ "peas", "porridge", "hot", "peas", "porridge", "cold", "peas", "porridge", "in", "the", "pot", "nine", "days", "old" }; - int num=5,width=15; boost::coroutines2::coroutine::push_type writer( [&](boost::coroutines2::coroutine::pull_type& in){ @@ -46,10 +44,7 @@ int main(int argc,char* argv[]){ std::cout << std::endl; } }); - std::copy(begin(words),end(words),begin(writer)); - - std::cout << "\nDone" << std::endl; - - return 0; + std::cout << "\nDone"; + return EXIT_SUCCESS; } diff --git a/example/parser.cpp b/example/parser.cpp index 16882a8..7aef477 100644 --- a/example/parser.cpp +++ b/example/parser.cpp @@ -108,14 +108,11 @@ int main() { }); p.run(); }); - // user-code pulls parsed data from parser for(char c:seq){ printf("Parsed: %c\n",c); } - std::cout << "\nDone" << std::endl; - return EXIT_SUCCESS; } catch ( std::exception const& ex) { std::cerr << "exception: " << ex.what() << std::endl; diff --git a/example/same_fringe.cpp b/example/same_fringe.cpp index 78956e1..9903f6b 100644 --- a/example/same_fringe.cpp +++ b/example/same_fringe.cpp @@ -13,8 +13,7 @@ #include -struct node -{ +struct node { typedef std::shared_ptr< node > ptr_t; // Each tree node has an optional left subtree, an optional right subtree @@ -25,26 +24,24 @@ struct node // construct leaf node(const std::string& v): - left(),right(),value(v) - {} + left(),right(),value(v) { + } + // construct nonleaf node(ptr_t l, const std::string& v, ptr_t r): - left(l),right(r),value(v) - {} + left(l),right(r),value(v) { + } - static ptr_t create(const std::string& v) - { + static ptr_t create(const std::string& v) { return ptr_t(new node(v)); } - static ptr_t create(ptr_t l, const std::string& v, ptr_t r) - { + static ptr_t create(ptr_t l, const std::string& v, ptr_t r) { return ptr_t(new node(l, v, r)); } }; -node::ptr_t create_left_tree_from(const std::string& root) -{ +node::ptr_t create_left_tree_from(const std::string& root) { /* -------- root / \ @@ -62,8 +59,7 @@ node::ptr_t create_left_tree_from(const std::string& root) node::create("e")); } -node::ptr_t create_right_tree_from(const std::string& root) -{ +node::ptr_t create_right_tree_from(const std::string& root) { /* -------- root / \ @@ -82,8 +78,7 @@ node::ptr_t create_right_tree_from(const std::string& root) } // recursively walk the tree, delivering values in order -void traverse(node::ptr_t n, boost::coroutines2::coroutine::push_type& out) -{ +void traverse(node::ptr_t n, boost::coroutines2::coroutine::push_type& out) { if (n->left) traverse(n->left,out); out(n->value); @@ -91,8 +86,7 @@ void traverse(node::ptr_t n, boost::coroutines2::coroutine::push_ty traverse(n->right,out); } -int main() -{ +int main() { { node::ptr_t left_d(create_left_tree_from("d")); boost::coroutines2::coroutine::pull_type left_d_reader( @@ -127,7 +121,6 @@ int main() std::ostream_iterator(std::cout, " ")); std::cout << std::endl; } - { node::ptr_t left_d(create_left_tree_from("d")); boost::coroutines2::coroutine::pull_type left_d_reader( @@ -148,7 +141,6 @@ int main() begin(right_b_reader)) << std::endl; } - { node::ptr_t left_d(create_left_tree_from("d")); boost::coroutines2::coroutine::pull_type left_d_reader( @@ -169,8 +161,6 @@ int main() begin(right_x_reader)) << std::endl; } - std::cout << "Done" << std::endl; - return EXIT_SUCCESS; } diff --git a/example/segmented.cpp b/example/segmented.cpp index 3486183..b73ec72 100644 --- a/example/segmented.cpp +++ b/example/segmented.cpp @@ -54,7 +54,7 @@ int main() { sink(); - std::cout << "main: done" << std::endl; + std::cout << "main: Done" << std::endl; return 0; } diff --git a/example/simple.cpp b/example/simple.cpp index 0b69592..1c0bd1a 100644 --- a/example/simple.cpp +++ b/example/simple.cpp @@ -9,15 +9,12 @@ #include -int main() -{ +int main() { boost::coroutines2::coroutine< void >::push_type sink( - [&]( boost::coroutines2::coroutine< void >::pull_type & source) { + []( boost::coroutines2::coroutine< void >::pull_type & source) { std::cout << "inside coroutine-fn" << std::endl; }); sink(); - std::cout << "Done" << std::endl; - return EXIT_SUCCESS; } diff --git a/include/boost/coroutine2/detail/create_control_block.ipp b/include/boost/coroutine2/detail/create_control_block.ipp new file mode 100644 index 0000000..0645436 --- /dev/null +++ b/include/boost/coroutine2/detail/create_control_block.ipp @@ -0,0 +1,60 @@ + +// Copyright Oliver Kowalke 2014. +// 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_COROUTINES2_DETAIL_CREATE_CONTROLBLOCK_IPP +#define BOOST_COROUTINES2_DETAIL_CREATE_CONTROLBLOCK_IPP + +#include +#include +#include + +#include +#include + +#include +#include + +#include + +#ifdef BOOST_HAS_ABI_HEADERS +# include BOOST_ABI_PREFIX +#endif + +namespace boost { +namespace coroutines2 { +namespace detail { + +template< typename ControlBlock, typename StackAllocator, typename Fn > +ControlBlock * create_control_block( StackAllocator salloc, Fn && fn) { + auto sctx = salloc.allocate(); + // reserve space for control structure +#if defined(BOOST_NO_CXX14_CONSTEXPR) || defined(BOOST_NO_CXX11_STD_ALIGN) + void * sp = static_cast< char * >( sctx.sp) - sizeof( ControlBlock); + std::size_t size = sctx.size - sizeof( ControlBlock); +#else + constexpr std::size_t func_alignment = 64; // alignof( ControlBlock); + constexpr std::size_t func_size = sizeof( ControlBlock); + // reserve space on stack + void * sp = static_cast< char * >( sctx.sp) - func_size - func_alignment; + // align sp pointer + std::size_t space = func_size + func_alignment; + sp = std::align( func_alignment, func_size, sp, space); + BOOST_ASSERT( nullptr != sp); + // calculate remaining size + std::size_t size = sctx.size - ( static_cast< char * >( sctx.sp) - static_cast< char * >( sp) ); +#endif + // placment new for control structure on coroutine stack + return new ( sp) ControlBlock{ context::preallocated( sp, size, sctx), + salloc, std::forward< Fn >( fn) }; +} + +}}} + +#ifdef BOOST_HAS_ABI_HEADERS +# include BOOST_ABI_SUFFIX +#endif + +#endif // BOOST_COROUTINES2_DETAIL_CREATE_CONTROLBLOCK_IPP diff --git a/include/boost/coroutine2/detail/forced_unwind.hpp b/include/boost/coroutine2/detail/forced_unwind.hpp index e04eb72..0f67f79 100644 --- a/include/boost/coroutine2/detail/forced_unwind.hpp +++ b/include/boost/coroutine2/detail/forced_unwind.hpp @@ -24,6 +24,12 @@ namespace detail { struct forced_unwind {}; +inline +void * unwind_coroutine( void * data) { + throw forced_unwind{}; + return data; +} + }}} #ifdef BOOST_HAS_ABI_HEADERS diff --git a/include/boost/coroutine2/detail/pull_control_block.hpp b/include/boost/coroutine2/detail/pull_control_block.hpp index 7009454..45b655b 100644 --- a/include/boost/coroutine2/detail/pull_control_block.hpp +++ b/include/boost/coroutine2/detail/pull_control_block.hpp @@ -13,6 +13,8 @@ #include #include +#include + #ifdef BOOST_HAS_ABI_HEADERS # include BOOST_ABI_PREFIX #endif @@ -25,18 +27,17 @@ template< typename T > struct pull_coroutine< T >::control_block { typename push_coroutine< T >::control_block * other; boost::context::execution_context ctx; - bool preserve_fpu; - int state; + state_t 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); + control_block( context::preallocated, StackAllocator, Fn &&); - explicit control_block( typename push_coroutine< T >::control_block *, boost::context::execution_context const&); + control_block( typename push_coroutine< T >::control_block *, boost::context::execution_context const&) noexcept; - ~control_block(); + ~control_block() noexcept; control_block( control_block &) = delete; control_block & operator=( control_block &) = delete; @@ -45,7 +46,7 @@ struct pull_coroutine< T >::control_block { void set( T *); - T & get(); + T & get() noexcept; bool valid() const noexcept; }; @@ -54,24 +55,23 @@ template< typename T > struct pull_coroutine< T & >::control_block { typename push_coroutine< T & >::control_block * other; boost::context::execution_context ctx; - bool preserve_fpu; - int state; + state_t state; std::exception_ptr except; T * t; template< typename StackAllocator, typename Fn > - control_block( context::preallocated, StackAllocator, Fn &&, bool); + control_block( context::preallocated, StackAllocator, Fn &&); - explicit control_block( typename push_coroutine< T & >::control_block *, boost::context::execution_context const&); + control_block( typename push_coroutine< T & >::control_block *, boost::context::execution_context const&) noexcept; - ~control_block(); + ~control_block() noexcept; control_block( control_block &) = delete; control_block & operator=( control_block &) = delete; void resume(); - T & get(); + T & get() noexcept; bool valid() const noexcept; }; @@ -79,16 +79,15 @@ struct pull_coroutine< T & >::control_block { struct pull_coroutine< void >::control_block { push_coroutine< void >::control_block * other; boost::context::execution_context ctx; - bool preserve_fpu; - int state; + state_t state; std::exception_ptr except; template< typename StackAllocator, typename Fn > - control_block( context::preallocated, StackAllocator, Fn &&, bool); + control_block( context::preallocated, StackAllocator, Fn &&); - explicit control_block( push_coroutine< void >::control_block *, boost::context::execution_context const&); + control_block( push_coroutine< void >::control_block *, boost::context::execution_context const&) noexcept; - ~control_block(); + ~control_block() noexcept; control_block( control_block &) = delete; control_block & operator=( control_block &) = delete; diff --git a/include/boost/coroutine2/detail/pull_control_block.ipp b/include/boost/coroutine2/detail/pull_control_block.ipp index 536e5e6..d803755 100644 --- a/include/boost/coroutine2/detail/pull_control_block.ipp +++ b/include/boost/coroutine2/detail/pull_control_block.ipp @@ -32,13 +32,13 @@ namespace detail { template< typename T > template< typename StackAllocator, typename Fn > pull_coroutine< T >::control_block::control_block( context::preallocated palloc, StackAllocator salloc, - Fn && fn_, bool preserve_fpu_) : - other( nullptr), - ctx( std::allocator_arg, palloc, salloc, - [=,fn=std::forward< Fn >( fn_),ctx=boost::context::execution_context::current()] (void *) mutable -> void { + Fn && fn_) : + other{ nullptr }, + ctx{ std::allocator_arg, palloc, salloc, + [this,fn=std::forward< Fn >( fn_),ctx=boost::context::execution_context::current()] (void *) mutable noexcept { // create synthesized push_coroutine< T > - typename push_coroutine< T >::control_block synthesized_cb( this, ctx); - push_coroutine< T > synthesized( & synthesized_cb); + 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 @@ -50,39 +50,37 @@ pull_coroutine< T >::control_block::control_block( context::preallocated palloc, except = std::current_exception(); } // set termination flags - state |= static_cast< int >( state_t::complete); + state |= state_t::complete; // jump back to ctx - other->ctx( nullptr, preserve_fpu); + other->ctx(); BOOST_ASSERT_MSG( false, "pull_coroutine is complete"); - }), - preserve_fpu( preserve_fpu_), - state( static_cast< int >( state_t::unwind) ), - except(), - bvalid( false), - storage() { + }}, + state{ state_t::unwind }, + 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) ) ); + set( static_cast< T * >( ctx() ) ); } template< typename T > pull_coroutine< T >::control_block::control_block( typename push_coroutine< T >::control_block * cb, - boost::context::execution_context const& ctx_) : - other( cb), - ctx( ctx_), - preserve_fpu( other->preserve_fpu), - state( 0), - except(), - bvalid( false), - storage() { + boost::context::execution_context const& ctx_) noexcept : + other{ cb }, + ctx{ ctx_ }, + state{ state_t::none }, + except{}, + bvalid{ false }, + storage{} { } template< typename T > -pull_coroutine< T >::control_block::~control_block() { - if ( 0 == ( state & static_cast< int >( state_t::complete ) ) && - 0 != ( state & static_cast< int >( state_t::unwind) ) ) { +pull_coroutine< T >::control_block::~control_block() noexcept { + if ( state_t::none == ( state & state_t::complete) && + state_t::none != ( state & state_t::unwind) ) { // set early-exit flag - state |= static_cast< int >( state_t::early_exit); - ctx( nullptr, preserve_fpu); + state |= state_t::early_exit; + ctx(); } // destroy data if it set if ( bvalid) { @@ -94,12 +92,12 @@ template< typename T > void pull_coroutine< T >::control_block::resume() { other->ctx = boost::context::execution_context::current(); - set( reinterpret_cast< T * >( ctx( nullptr, preserve_fpu) ) ); + set( static_cast< T * >( ctx() ) ); if ( except) { std::rethrow_exception( except); } // test early-exit-flag - if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) { + if ( state_t::none != ( other->state & state_t::early_exit) ) { throw forced_unwind(); } } @@ -121,14 +119,14 @@ pull_coroutine< T >::control_block::set( T * t) { template< typename T > T & -pull_coroutine< T >::control_block::get() { +pull_coroutine< T >::control_block::get() noexcept { return * reinterpret_cast< T * >( storage); } template< typename T > bool pull_coroutine< T >::control_block::valid() const noexcept { - return nullptr != other && 0 == ( state & static_cast< int >( state_t::complete) ) && bvalid; + return nullptr != other && state_t::none == ( state & state_t::complete) && bvalid; } @@ -137,13 +135,13 @@ pull_coroutine< T >::control_block::valid() const noexcept { template< typename T > template< typename StackAllocator, typename Fn > pull_coroutine< T & >::control_block::control_block( context::preallocated palloc, StackAllocator salloc, - Fn && fn_, bool preserve_fpu_) : - other( nullptr), - ctx( std::allocator_arg, palloc, salloc, - [=,fn=std::forward< Fn >( fn_),ctx=boost::context::execution_context::current()] (void *) mutable -> void { + Fn && fn_) : + other{ nullptr }, + ctx{ std::allocator_arg, palloc, salloc, + [this,fn=std::forward< Fn >( fn_),ctx=boost::context::execution_context::current()] (void *) mutable noexcept { // create synthesized push_coroutine< T > - typename push_coroutine< T & >::control_block synthesized_cb( this, ctx); - push_coroutine< T & > synthesized( & synthesized_cb); + 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 @@ -155,37 +153,35 @@ pull_coroutine< T & >::control_block::control_block( context::preallocated pallo except = std::current_exception(); } // set termination flags - state |= static_cast< int >( state_t::complete); + state |= state_t::complete; // jump back to ctx - other->ctx( nullptr, preserve_fpu); + other->ctx(); BOOST_ASSERT_MSG( false, "pull_coroutine is complete"); - }), - preserve_fpu( preserve_fpu_), - state( static_cast< int >( state_t::unwind) ), - except(), + }}, + state{ state_t::unwind }, + 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) ); + t = static_cast< T * >( ctx() ); } template< typename T > pull_coroutine< T & >::control_block::control_block( typename push_coroutine< T & >::control_block * cb, - boost::context::execution_context const& ctx_) : - other( cb), - ctx( ctx_), - preserve_fpu( other->preserve_fpu), - state( 0), - except(), + boost::context::execution_context const& ctx_) noexcept : + other{ cb }, + ctx{ ctx_ }, + state{ state_t::none }, + except{}, t( nullptr) { } template< typename T > -pull_coroutine< T & >::control_block::~control_block() { - if ( 0 == ( state & static_cast< int >( state_t::complete ) ) && - 0 != ( state & static_cast< int >( state_t::unwind) ) ) { +pull_coroutine< T & >::control_block::~control_block() noexcept { + if ( state_t::none == ( state & state_t::complete) && + state_t::none != ( state & state_t::unwind) ) { // set early-exit flag - state |= static_cast< int >( state_t::early_exit); - ctx( nullptr, preserve_fpu); + state |= state_t::early_exit; + ctx(); } } @@ -193,26 +189,26 @@ template< typename T > void pull_coroutine< T & >::control_block::resume() { other->ctx = boost::context::execution_context::current(); - t = reinterpret_cast< T * >( ctx( nullptr, preserve_fpu) ); + t = static_cast< T * >( ctx() ); if ( except) { std::rethrow_exception( except); } // test early-exit-flag - if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) { + if ( state_t::none != ( other->state & state_t::early_exit) ) { throw forced_unwind(); } } template< typename T > T & -pull_coroutine< T & >::control_block::get() { - return * reinterpret_cast< T * >( t); +pull_coroutine< T & >::control_block::get() noexcept { + return * static_cast< T * >( t); } template< typename T > bool pull_coroutine< T & >::control_block::valid() const noexcept { - return nullptr != other && 0 == ( state & static_cast< int >( state_t::complete) ) && nullptr != t; + return nullptr != other && state_t::none == ( state & state_t::complete) && nullptr != t; } @@ -220,13 +216,13 @@ pull_coroutine< T & >::control_block::valid() const noexcept { template< typename StackAllocator, typename Fn > pull_coroutine< void >::control_block::control_block( context::preallocated palloc, StackAllocator salloc, - Fn && fn_, bool preserve_fpu_) : - other( nullptr), - ctx( std::allocator_arg, palloc, salloc, - [=,fn=std::forward< Fn >( fn_),ctx=boost::context::execution_context::current()] (void *) mutable -> void { + Fn && fn_) : + other{ nullptr }, + ctx{ std::allocator_arg, palloc, salloc, + [this,fn=std::forward< Fn >( fn_),ctx=boost::context::execution_context::current()] (void *) mutable noexcept { // create synthesized push_coroutine< T > - typename push_coroutine< void >::control_block synthesized_cb( this, ctx); - push_coroutine< void > synthesized( & synthesized_cb); + 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 @@ -238,35 +234,33 @@ pull_coroutine< void >::control_block::control_block( context::preallocated pall except = std::current_exception(); } // set termination flags - state |= static_cast< int >( state_t::complete); + state |= state_t::complete; // jump back to ctx - other->ctx( nullptr, preserve_fpu); + other->ctx(); BOOST_ASSERT_MSG( false, "pull_coroutine is complete"); - }), - preserve_fpu( preserve_fpu_), - state( static_cast< int >( state_t::unwind) ), - except() { + }}, + state{ state_t::unwind }, + except{} { // enter coroutine-fn in order to have first value available after ctor returns - ctx( nullptr, preserve_fpu); + ctx(); } inline pull_coroutine< void >::control_block::control_block( push_coroutine< void >::control_block * cb, - boost::context::execution_context const& ctx_) : - other( cb), - ctx( ctx_), - preserve_fpu( other->preserve_fpu), - state( 0), - except() { + boost::context::execution_context const& ctx_) noexcept : + other{ cb }, + ctx{ ctx_ }, + state{ state_t::none }, + except{} { } inline -pull_coroutine< void >::control_block::~control_block() { - if ( 0 == ( state & static_cast< int >( state_t::complete ) ) && - 0 != ( state & static_cast< int >( state_t::unwind) ) ) { +pull_coroutine< void >::control_block::~control_block() noexcept { + if ( state_t::none == ( state & state_t::complete) && + state_t::none != ( state & state_t::unwind) ) { // set early-exit flag - state |= static_cast< int >( state_t::early_exit); - ctx( nullptr, preserve_fpu); + state |= state_t::early_exit; + ctx(); } } @@ -274,12 +268,12 @@ inline void pull_coroutine< void >::control_block::resume() { other->ctx = boost::context::execution_context::current(); - ctx( nullptr, preserve_fpu); + ctx(); if ( except) { std::rethrow_exception( except); } // test early-exit-flag - if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) { + if ( state_t::none != ( other->state & state_t::early_exit) ) { throw forced_unwind(); } } @@ -287,7 +281,7 @@ pull_coroutine< void >::control_block::resume() { inline bool pull_coroutine< void >::control_block::valid() const noexcept { - return nullptr != other && 0 == ( state & static_cast< int >( state_t::complete) ); + return nullptr != other && state_t::none == ( state & state_t::complete); } }}} diff --git a/include/boost/coroutine2/detail/pull_coroutine.hpp b/include/boost/coroutine2/detail/pull_coroutine.hpp index c787504..0690fb5 100644 --- a/include/boost/coroutine2/detail/pull_coroutine.hpp +++ b/include/boost/coroutine2/detail/pull_coroutine.hpp @@ -12,7 +12,6 @@ #include #include -#include #include @@ -34,25 +33,25 @@ private: control_block * cb_; - explicit pull_coroutine( control_block *); + explicit pull_coroutine( control_block *) noexcept; - bool has_result_() const; + bool has_result_() const noexcept; public: template< typename Fn > - explicit pull_coroutine( Fn &&, bool = false); + explicit pull_coroutine( Fn &&); template< typename StackAllocator, typename Fn > - explicit pull_coroutine( StackAllocator, Fn &&, bool = false); + pull_coroutine( StackAllocator, Fn &&); - ~pull_coroutine(); + ~pull_coroutine() noexcept; pull_coroutine( pull_coroutine const&) = delete; pull_coroutine & operator=( pull_coroutine const&) = delete; - pull_coroutine( pull_coroutine &&); + pull_coroutine( pull_coroutine &&) noexcept; - pull_coroutine & operator=( pull_coroutine && other) { + pull_coroutine & operator=( pull_coroutine && other) noexcept { if ( this != & other) { cb_ = other.cb_; other.cb_ = nullptr; @@ -66,7 +65,7 @@ public: bool operator!() const noexcept; - T get(); + T get() noexcept; class iterator : public std::iterator< std::input_iterator_tag, typename std::remove_reference< T >::type > { private: @@ -91,30 +90,31 @@ public: typedef typename iterator::pointer pointer_t; typedef typename iterator::reference reference_t; - iterator() : - c_( nullptr) { + iterator() noexcept : + c_{ nullptr } { } explicit iterator( pull_coroutine< T > * c) : - c_( c) { + c_{ c } { fetch_(); } - iterator( iterator const& other) : - c_( other.c_) { + iterator( iterator const& other) noexcept : + c_{ other.c_ } { } - iterator & operator=( iterator const& other) { - if ( this == & other) return * this; - c_ = other.c_; + iterator & operator=( iterator const& other) noexcept { + if ( this != & other) { + c_ = other.c_; + } return * this; } - bool operator==( iterator const& other) const { + bool operator==( iterator const& other) const noexcept { return other.c_ == c_; } - bool operator!=( iterator const& other) const { + bool operator!=( iterator const& other) const noexcept { return other.c_ != c_; } @@ -125,11 +125,11 @@ public: iterator operator++( int) = delete; - reference_t operator*() const { + reference_t operator*() const noexcept { return c_->cb_->get(); } - pointer_t operator->() const { + pointer_t operator->() const noexcept { return std::addressof( c_->cb_->get() ); } }; @@ -147,25 +147,25 @@ private: control_block * cb_; - explicit pull_coroutine( control_block *); + explicit pull_coroutine( control_block *) noexcept; - bool has_result_() const; + bool has_result_() const noexcept; public: template< typename Fn > - explicit pull_coroutine( Fn &&, bool = false); + explicit pull_coroutine( Fn &&); template< typename StackAllocator, typename Fn > - explicit pull_coroutine( StackAllocator, Fn &&, bool = false); + pull_coroutine( StackAllocator, Fn &&); - ~pull_coroutine(); + ~pull_coroutine() noexcept; pull_coroutine( pull_coroutine const&) = delete; pull_coroutine & operator=( pull_coroutine const&) = delete; - pull_coroutine( pull_coroutine &&); + pull_coroutine( pull_coroutine &&) noexcept; - pull_coroutine & operator=( pull_coroutine && other) { + pull_coroutine & operator=( pull_coroutine && other) noexcept { if ( this != & other) { cb_ = other.cb_; other.cb_ = nullptr; @@ -179,7 +179,7 @@ public: bool operator!() const noexcept; - T & get(); + T & get() noexcept; class iterator : public std::iterator< std::input_iterator_tag, typename std::remove_reference< T >::type > { private: @@ -204,30 +204,31 @@ public: typedef typename iterator::pointer pointer_t; typedef typename iterator::reference reference_t; - iterator() : - c_( nullptr) { + iterator() noexcept : + c_{ nullptr } { } explicit iterator( pull_coroutine< T & > * c) : - c_( c) { + c_{ c } { fetch_(); } - iterator( iterator const& other) : - c_( other.c_) { + iterator( iterator const& other) noexcept : + c_{ other.c_ } { } - iterator & operator=( iterator const& other) { - if ( this == & other) return * this; - c_ = other.c_; + iterator & operator=( iterator const& other) noexcept { + if ( this != & other) { + c_ = other.c_; + } return * this; } - bool operator==( iterator const& other) const { + bool operator==( iterator const& other) const noexcept { return other.c_ == c_; } - bool operator!=( iterator const& other) const { + bool operator!=( iterator const& other) const noexcept { return other.c_ != c_; } @@ -238,11 +239,11 @@ public: iterator operator++( int) = delete; - reference_t operator*() const { + reference_t operator*() const noexcept { return c_->cb_->get(); } - pointer_t operator->() const { + pointer_t operator->() const noexcept { return std::addressof( c_->cb_->get() ); } }; @@ -260,23 +261,23 @@ private: control_block * cb_; - explicit pull_coroutine( control_block *); + explicit pull_coroutine( control_block *) noexcept; public: template< typename Fn > - explicit pull_coroutine( Fn &&, bool = false); + explicit pull_coroutine( Fn &&); template< typename StackAllocator, typename Fn > - explicit pull_coroutine( StackAllocator, Fn &&, bool = false); + pull_coroutine( StackAllocator, Fn &&); - ~pull_coroutine(); + ~pull_coroutine() noexcept; pull_coroutine( pull_coroutine const&) = delete; pull_coroutine & operator=( pull_coroutine const&) = delete; - pull_coroutine( pull_coroutine &&); + pull_coroutine( pull_coroutine &&) noexcept; - pull_coroutine & operator=( pull_coroutine && other) { + pull_coroutine & operator=( pull_coroutine && other) noexcept { if ( this != & other) { cb_ = other.cb_; other.cb_ = nullptr; diff --git a/include/boost/coroutine2/detail/pull_coroutine.ipp b/include/boost/coroutine2/detail/pull_coroutine.ipp index 2e37ef2..1c63982 100644 --- a/include/boost/coroutine2/detail/pull_coroutine.ipp +++ b/include/boost/coroutine2/detail/pull_coroutine.ipp @@ -8,16 +8,13 @@ #define BOOST_COROUTINES2_DETAIL_PULL_COROUTINE_IPP #include -#include #include #include #include -#include -#include - #include +#include #include #include @@ -32,57 +29,41 @@ namespace detail { // pull_coroutine< T > template< typename T > -pull_coroutine< T >::pull_coroutine( control_block * cb) : - cb_( cb) { +pull_coroutine< T >::pull_coroutine( control_block * cb) noexcept : + cb_{ cb } { } template< typename T > bool -pull_coroutine< T >::has_result_() const { +pull_coroutine< T >::has_result_() const noexcept { return nullptr != cb_->other->t; } template< typename T > template< typename Fn > -pull_coroutine< T >::pull_coroutine( Fn && fn, bool preserve_fpu) : - pull_coroutine( default_stack(), std::forward< Fn >( fn), preserve_fpu) { +pull_coroutine< T >::pull_coroutine( Fn && fn) : + pull_coroutine{ default_stack(), std::forward< Fn >( fn) } { } template< typename T > template< typename StackAllocator, typename Fn > -pull_coroutine< T >::pull_coroutine( StackAllocator salloc, Fn && fn, bool preserve_fpu) : - cb_( nullptr) { - context::stack_context sctx( salloc.allocate() ); - // reserve space for control structure -#if defined(BOOST_NO_CXX14_CONSTEXPR) || defined(BOOST_NO_CXX11_STD_ALIGN) - void * sp = static_cast< char * >( sctx.sp) - sizeof( control_block); - std::size_t size = sctx.size - sizeof( control_block); -#else - constexpr std::size_t func_alignment = 64; // alignof( control_block); - constexpr std::size_t func_size = sizeof( control_block); - // reserve space on stack - void * sp = static_cast< char * >( sctx.sp) - func_size - func_alignment; - // align sp pointer - std::size_t space = func_size + func_alignment; - sp = std::align( func_alignment, func_size, sp, space); - BOOST_ASSERT( nullptr != sp); - // calculate remaining size - std::size_t size = sctx.size - ( static_cast< char * >( sctx.sp) - static_cast< char * >( sp) ); -#endif - // placment new for control structure on coroutine stack - cb_ = new ( sp) control_block( context::preallocated( sp, size, sctx), - salloc, std::forward< Fn >( fn), preserve_fpu); +pull_coroutine< T >::pull_coroutine( StackAllocator salloc, Fn && fn) : + cb_{ create_control_block< control_block >( salloc, std::forward< Fn >( fn) ) } { + if ( ! cb_->valid() ) { + cb_->~control_block(); + cb_ = nullptr; + } } template< typename T > -pull_coroutine< T >::~pull_coroutine() { +pull_coroutine< T >::~pull_coroutine() noexcept { if ( nullptr != cb_) { cb_->~control_block(); } } template< typename T > -pull_coroutine< T >::pull_coroutine( pull_coroutine && other) : +pull_coroutine< T >::pull_coroutine( pull_coroutine && other) noexcept : cb_( other.cb_) { other.cb_ = nullptr; } @@ -107,7 +88,7 @@ pull_coroutine< T >::operator!() const noexcept { template< typename T > T -pull_coroutine< T >::get() { +pull_coroutine< T >::get() noexcept { return std::move( cb_->get() ); } @@ -115,57 +96,41 @@ pull_coroutine< T >::get() { // pull_coroutine< T & > template< typename T > -pull_coroutine< T & >::pull_coroutine( control_block * cb) : +pull_coroutine< T & >::pull_coroutine( control_block * cb) noexcept : cb_( cb) { } template< typename T > bool -pull_coroutine< T & >::has_result_() const { +pull_coroutine< T & >::has_result_() const noexcept { return nullptr != cb_->other->t; } template< typename T > template< typename Fn > -pull_coroutine< T & >::pull_coroutine( Fn && fn, bool preserve_fpu) : - pull_coroutine( default_stack(), std::forward< Fn >( fn), preserve_fpu) { +pull_coroutine< T & >::pull_coroutine( Fn && fn) : + pull_coroutine{ default_stack(), std::forward< Fn >( fn) } { } template< typename T > template< typename StackAllocator, typename Fn > -pull_coroutine< T & >::pull_coroutine( StackAllocator salloc, Fn && fn, bool preserve_fpu) : - cb_( nullptr) { - context::stack_context sctx( salloc.allocate() ); - // reserve space for control structure -#if defined(BOOST_NO_CXX14_CONSTEXPR) || defined(BOOST_NO_CXX11_STD_ALIGN) - void * sp = static_cast< char * >( sctx.sp) - sizeof( control_block); - std::size_t size = sctx.size - sizeof( control_block); -#else - constexpr std::size_t func_alignment = 64; // alignof( control_block); - constexpr std::size_t func_size = sizeof( control_block); - // reserve space on stack - void * sp = static_cast< char * >( sctx.sp) - func_size - func_alignment; - // align sp pointer - std::size_t space = func_size + func_alignment; - sp = std::align( func_alignment, func_size, sp, space); - BOOST_ASSERT( nullptr != sp); - // calculate remaining size - std::size_t size = sctx.size - ( static_cast< char * >( sctx.sp) - static_cast< char * >( sp) ); -#endif - // placment new for control structure on coroutine stack - cb_ = new ( sp) control_block( context::preallocated( sp, size, sctx), - salloc, std::forward< Fn >( fn), preserve_fpu); +pull_coroutine< T & >::pull_coroutine( StackAllocator salloc, Fn && fn) : + cb_{ create_control_block< control_block >( salloc, std::forward< Fn >( fn) ) } { + if ( ! cb_->valid() ) { + cb_->~control_block(); + cb_ = nullptr; + } } template< typename T > -pull_coroutine< T & >::~pull_coroutine() { +pull_coroutine< T & >::~pull_coroutine() noexcept { if ( nullptr != cb_) { cb_->~control_block(); } } template< typename T > -pull_coroutine< T & >::pull_coroutine( pull_coroutine && other) : +pull_coroutine< T & >::pull_coroutine( pull_coroutine && other) noexcept : cb_( other.cb_) { other.cb_ = nullptr; } @@ -190,7 +155,7 @@ pull_coroutine< T & >::operator!() const noexcept { template< typename T > T & -pull_coroutine< T & >::get() { +pull_coroutine< T & >::get() noexcept { return cb_->get(); } @@ -198,49 +163,33 @@ pull_coroutine< T & >::get() { // pull_coroutine< void > inline -pull_coroutine< void >::pull_coroutine( control_block * cb) : +pull_coroutine< void >::pull_coroutine( control_block * cb) noexcept : cb_( cb) { } template< typename Fn > -pull_coroutine< void >::pull_coroutine( Fn && fn, bool preserve_fpu) : - pull_coroutine( default_stack(), std::forward< Fn >( fn), preserve_fpu) { +pull_coroutine< void >::pull_coroutine( Fn && fn) : + pull_coroutine{ default_stack(), std::forward< Fn >( fn) } { } template< typename StackAllocator, typename Fn > -pull_coroutine< void >::pull_coroutine( StackAllocator salloc, Fn && fn, bool preserve_fpu) : - cb_( nullptr) { - context::stack_context sctx( salloc.allocate() ); - // reserve space for control structure -#if defined(BOOST_NO_CXX14_CONSTEXPR) || defined(BOOST_NO_CXX11_STD_ALIGN) - void * sp = static_cast< char * >( sctx.sp) - sizeof( control_block); - std::size_t size = sctx.size - sizeof( control_block); -#else - constexpr std::size_t func_alignment = 64; // alignof( control_block); - constexpr std::size_t func_size = sizeof( control_block); - // reserve space on stack - void * sp = static_cast< char * >( sctx.sp) - func_size - func_alignment; - // align sp pointer - std::size_t space = func_size + func_alignment; - sp = std::align( func_alignment, func_size, sp, space); - BOOST_ASSERT( nullptr != sp); - // calculate remaining size - std::size_t size = sctx.size - ( static_cast< char * >( sctx.sp) - static_cast< char * >( sp) ); -#endif - // placment new for control structure on coroutine stack - cb_ = new ( sp) control_block( context::preallocated( sp, size, sctx), - salloc, std::forward< Fn >( fn), preserve_fpu); +pull_coroutine< void >::pull_coroutine( StackAllocator salloc, Fn && fn) : + cb_{ create_control_block< control_block >( salloc, std::forward< Fn >( fn) ) } { + if ( ! cb_->valid() ) { + cb_->~control_block(); + cb_ = nullptr; + } } inline -pull_coroutine< void >::~pull_coroutine() { +pull_coroutine< void >::~pull_coroutine() noexcept { if ( nullptr != cb_) { cb_->~control_block(); } } inline -pull_coroutine< void >::pull_coroutine( pull_coroutine && other) : +pull_coroutine< void >::pull_coroutine( pull_coroutine && other) noexcept : cb_( other.cb_) { other.cb_ = nullptr; } diff --git a/include/boost/coroutine2/detail/push_control_block.hpp b/include/boost/coroutine2/detail/push_control_block.hpp index 03aa912..c0c3cc5 100644 --- a/include/boost/coroutine2/detail/push_control_block.hpp +++ b/include/boost/coroutine2/detail/push_control_block.hpp @@ -12,6 +12,8 @@ #include #include +#include + #ifdef BOOST_HAS_ABI_HEADERS # include BOOST_ABI_PREFIX #endif @@ -24,16 +26,15 @@ template< typename T > struct push_coroutine< T >::control_block { typename pull_coroutine< T >::control_block * other; boost::context::execution_context ctx; - bool preserve_fpu; - int state; + state_t state; std::exception_ptr except; template< typename StackAllocator, typename Fn > - control_block( context::preallocated, StackAllocator, Fn &&, bool); + control_block( context::preallocated, StackAllocator, Fn &&); - explicit control_block( typename pull_coroutine< T >::control_block *, boost::context::execution_context const&); + control_block( typename pull_coroutine< T >::control_block *, boost::context::execution_context const&) noexcept; - ~control_block(); + ~control_block() noexcept; control_block( control_block &) = delete; control_block & operator=( control_block &) = delete; @@ -49,16 +50,15 @@ template< typename T > struct push_coroutine< T & >::control_block { typename pull_coroutine< T & >::control_block * other; boost::context::execution_context ctx; - bool preserve_fpu; - int state; + state_t state; std::exception_ptr except; template< typename StackAllocator, typename Fn > - control_block( context::preallocated, StackAllocator, Fn &&, bool); + control_block( context::preallocated, StackAllocator, Fn &&); - explicit control_block( typename pull_coroutine< T & >::control_block *, boost::context::execution_context const&); + control_block( typename pull_coroutine< T & >::control_block *, boost::context::execution_context const&) noexcept; - ~control_block(); + ~control_block() noexcept; control_block( control_block &) = delete; control_block & operator=( control_block &) = delete; @@ -71,16 +71,15 @@ struct push_coroutine< T & >::control_block { struct push_coroutine< void >::control_block { pull_coroutine< void >::control_block * other; boost::context::execution_context ctx; - bool preserve_fpu; - int state; + state_t state; std::exception_ptr except; template< typename StackAllocator, typename Fn > - control_block( context::preallocated, StackAllocator, Fn &&, bool); + control_block( context::preallocated, StackAllocator, Fn &&); - explicit control_block( pull_coroutine< void >::control_block *, boost::context::execution_context const&); + control_block( pull_coroutine< void >::control_block *, boost::context::execution_context const&) noexcept; - ~control_block(); + ~control_block() noexcept; control_block( control_block &) = delete; control_block & operator=( control_block &) = delete; diff --git a/include/boost/coroutine2/detail/push_control_block.ipp b/include/boost/coroutine2/detail/push_control_block.ipp index ce6776f..473a380 100644 --- a/include/boost/coroutine2/detail/push_control_block.ipp +++ b/include/boost/coroutine2/detail/push_control_block.ipp @@ -33,16 +33,16 @@ namespace detail { template< typename T > template< typename StackAllocator, typename Fn > push_coroutine< T >::control_block::control_block( context::preallocated palloc, StackAllocator salloc, - Fn && fn_, bool preserve_fpu_) : - other( nullptr), - ctx( std::allocator_arg, palloc, salloc, - [=,fn=std::forward< Fn >( fn_),ctx=boost::context::execution_context::current()] (void *) mutable -> void { + Fn && fn_) : + other{ nullptr }, + ctx{ std::allocator_arg, palloc, salloc, + [this,fn=std::forward< Fn >( fn_),ctx=boost::context::execution_context::current()] (void *) mutable noexcept { // create synthesized pull_coroutine< T > - typename pull_coroutine< T >::control_block synthesized_cb( this, ctx); - pull_coroutine< T > synthesized( & synthesized_cb); + 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) ); + T * t = static_cast< T * >( ctx() ); // set transferred value synthesized_cb.set( t); try { @@ -55,35 +55,33 @@ push_coroutine< T >::control_block::control_block( context::preallocated palloc, except = std::current_exception(); } // set termination flags - state |= static_cast< int >( state_t::complete); + state |= state_t::complete; // jump back to ctx - other->ctx( nullptr, preserve_fpu); + other->ctx(); BOOST_ASSERT_MSG( false, "push_coroutine is complete"); - }), - preserve_fpu( preserve_fpu_), - state( static_cast< int >( state_t::unwind) ), - except() { + }}, + state{ state_t::unwind }, + except{} { // enter coroutine-fn in order to get other set - ctx( nullptr, preserve_fpu); + ctx(); } template< typename T > push_coroutine< T >::control_block::control_block( typename pull_coroutine< T >::control_block * cb, - boost::context::execution_context const& ctx_) : - other( cb), - ctx( ctx_), - preserve_fpu( other->preserve_fpu), - state( 0), - except() { + boost::context::execution_context const& ctx_) noexcept : + other{ cb }, + ctx{ ctx_ }, + state{ state_t::none }, + except{} { } template< typename T > -push_coroutine< T >::control_block::~control_block() { - if ( 0 == ( state & static_cast< int >( state_t::complete ) ) && - 0 != ( state & static_cast< int >( state_t::unwind) ) ) { +push_coroutine< T >::control_block::~control_block() noexcept { + if ( state_t::none == ( state & state_t::complete) && + state_t::none != ( state & state_t::unwind) ) { // set early-exit flag - state |= static_cast< int >( state_t::early_exit); - ctx( nullptr, preserve_fpu); + state |= state_t::early_exit; + ctx(); } } @@ -92,12 +90,12 @@ void 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); + ctx( const_cast< T * >( & t) ); if ( except) { std::rethrow_exception( except); } // test early-exit-flag - if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) { + if ( state_t::none != ( other->state & state_t::early_exit) ) { throw forced_unwind(); } } @@ -107,12 +105,12 @@ void 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); + ctx( std::addressof( t) ); if ( except) { std::rethrow_exception( except); } // test early-exit-flag - if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) { + if ( state_t::none != ( other->state & state_t::early_exit) ) { throw forced_unwind(); } } @@ -120,7 +118,7 @@ push_coroutine< T >::control_block::resume( T && t) { template< typename T > bool push_coroutine< T >::control_block::valid() const noexcept { - return 0 == ( state & static_cast< int >( state_t::complete) ); + return state_t::none == ( state & state_t::complete ); } @@ -129,16 +127,16 @@ push_coroutine< T >::control_block::valid() const noexcept { template< typename T > template< typename StackAllocator, typename Fn > push_coroutine< T & >::control_block::control_block( context::preallocated palloc, StackAllocator salloc, - Fn && fn_, bool preserve_fpu_) : - other( nullptr), - ctx( std::allocator_arg, palloc, salloc, - [=,fn=std::forward< Fn >( fn_),ctx=boost::context::execution_context::current()] (void *) mutable -> void { + Fn && fn_) : + other{ nullptr }, + ctx{ std::allocator_arg, palloc, salloc, + [this,fn=std::forward< Fn >( fn_),ctx=boost::context::execution_context::current()] (void *) mutable noexcept { // create synthesized pull_coroutine< T > - typename pull_coroutine< T & >::control_block synthesized_cb( this, ctx); - pull_coroutine< T & > synthesized( & synthesized_cb); + 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) ); + T * t = static_cast< T * >( ctx() ); // set transferred value synthesized_cb.t = t; try { @@ -151,35 +149,33 @@ push_coroutine< T & >::control_block::control_block( context::preallocated pallo except = std::current_exception(); } // set termination flags - state |= static_cast< int >( state_t::complete); + state |= state_t::complete; // jump back to ctx - other->ctx( nullptr, preserve_fpu); + other->ctx(); BOOST_ASSERT_MSG( false, "push_coroutine is complete"); - }), - preserve_fpu( preserve_fpu_), - state( static_cast< int >( state_t::unwind) ), - except() { + }}, + state{ state_t::unwind }, + except{} { // enter coroutine-fn in order to get other set - ctx( nullptr, preserve_fpu); + ctx(); } template< typename T > push_coroutine< T & >::control_block::control_block( typename pull_coroutine< T & >::control_block * cb, - boost::context::execution_context const& ctx_) : - other( cb), - ctx( ctx_), - preserve_fpu( other->preserve_fpu), - state( 0), - except() { + boost::context::execution_context const& ctx_) noexcept : + other{ cb }, + ctx{ ctx_ }, + state{ state_t::none }, + except{} { } template< typename T > -push_coroutine< T & >::control_block::~control_block() { - if ( 0 == ( state & static_cast< int >( state_t::complete ) ) && - 0 != ( state & static_cast< int >( state_t::unwind) ) ) { +push_coroutine< T & >::control_block::~control_block() noexcept { + if ( state_t::none == ( state & state_t::complete) && + state_t::none != ( state & state_t::unwind) ) { // set early-exit flag - state |= static_cast< int >( state_t::early_exit); - ctx( nullptr, preserve_fpu); + state |= state_t::early_exit; + ctx(); } } @@ -188,12 +184,12 @@ void 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); + ctx( const_cast< typename std::remove_const< T >::type * >( std::addressof( t) ) ); if ( except) { std::rethrow_exception( except); } // test early-exit-flag - if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) { + if ( state_t::none != ( other->state & state_t::early_exit) ) { throw forced_unwind(); } } @@ -201,23 +197,23 @@ push_coroutine< T & >::control_block::resume( T & t) { template< typename T > bool push_coroutine< T & >::control_block::valid() const noexcept { - return 0 == ( state & static_cast< int >( state_t::complete) ); + return state_t::none == ( state & state_t::complete ); } // push_coroutine< void > template< typename StackAllocator, typename Fn > -push_coroutine< void >::control_block::control_block( context::preallocated palloc, StackAllocator salloc, Fn && fn_, bool preserve_fpu_) : - other( nullptr), - ctx( std::allocator_arg, palloc, salloc, - [=,fn=std::forward< Fn >( fn_),ctx=boost::context::execution_context::current()] (void *) mutable -> void { +push_coroutine< void >::control_block::control_block( context::preallocated palloc, StackAllocator salloc, Fn && fn_) : + other{ nullptr }, + ctx{ std::allocator_arg, palloc, salloc, + [this,fn=std::forward< Fn >( fn_),ctx=boost::context::execution_context::current()] (void *) mutable noexcept { // create synthesized pull_coroutine< T > - typename pull_coroutine< void >::control_block synthesized_cb( this, ctx); - pull_coroutine< void > synthesized( & synthesized_cb); + 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); + ctx(); try { // call coroutine-fn with synthesized pull_coroutine as argument fn( synthesized); @@ -228,35 +224,33 @@ push_coroutine< void >::control_block::control_block( context::preallocated pall except = std::current_exception(); } // set termination flags - state |= static_cast< int >( state_t::complete); + state |= state_t::complete; // jump back to ctx - other->ctx( nullptr, preserve_fpu); + other->ctx(); BOOST_ASSERT_MSG( false, "push_coroutine is complete"); - }), - preserve_fpu( preserve_fpu_), - state( static_cast< int >( state_t::unwind) ), - except() { + }}, + state{ state_t::unwind }, + except{} { // enter coroutine-fn in order to get other set - ctx( nullptr, preserve_fpu); + ctx(); } inline push_coroutine< void >::control_block::control_block( pull_coroutine< void >::control_block * cb, - boost::context::execution_context const& ctx_) : - other( cb), - ctx( ctx_), - preserve_fpu( other->preserve_fpu), - state( 0), - except() { + boost::context::execution_context const& ctx_) noexcept : + other{ cb }, + ctx{ ctx_ }, + state{ state_t::none }, + except{} { } inline -push_coroutine< void >::control_block::~control_block() { - if ( 0 == ( state & static_cast< int >( state_t::complete ) ) && - 0 != ( state & static_cast< int >( state_t::unwind) ) ) { +push_coroutine< void >::control_block::~control_block() noexcept { + if ( state_t::none == ( state & state_t::complete) && + state_t::none != ( state & state_t::unwind) ) { // set early-exit flag - state |= static_cast< int >( state_t::early_exit); - ctx( nullptr, preserve_fpu); + state |= state_t::early_exit; + ctx(); } } @@ -264,12 +258,12 @@ inline void push_coroutine< void >::control_block::resume() { other->ctx = boost::context::execution_context::current(); - ctx( nullptr, preserve_fpu); + ctx(); if ( except) { std::rethrow_exception( except); } // test early-exit-flag - if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) { + if ( state_t::none != ( other->state & state_t::early_exit) ) { throw forced_unwind(); } } @@ -277,7 +271,7 @@ push_coroutine< void >::control_block::resume() { inline bool push_coroutine< void >::control_block::valid() const noexcept { - return 0 == ( state & static_cast< int >( state_t::complete) ); + return state_t::none == ( state & state_t::complete ); } }}} diff --git a/include/boost/coroutine2/detail/push_coroutine.hpp b/include/boost/coroutine2/detail/push_coroutine.hpp index 1a2d01f..9807f1b 100644 --- a/include/boost/coroutine2/detail/push_coroutine.hpp +++ b/include/boost/coroutine2/detail/push_coroutine.hpp @@ -12,7 +12,6 @@ #include #include -#include #include @@ -34,23 +33,23 @@ private: control_block * cb_; - explicit push_coroutine( control_block *); + explicit push_coroutine( control_block *) noexcept; public: template< typename Fn > - explicit push_coroutine( Fn &&, bool = false); + explicit push_coroutine( Fn &&); template< typename StackAllocator, typename Fn > - explicit push_coroutine( StackAllocator, Fn &&, bool = false); + push_coroutine( StackAllocator, Fn &&); - ~push_coroutine(); + ~push_coroutine() noexcept; push_coroutine( push_coroutine const&) = delete; push_coroutine & operator=( push_coroutine const&) = delete; - push_coroutine( push_coroutine &&); + push_coroutine( push_coroutine &&) noexcept; - push_coroutine & operator=( push_coroutine && other) { + push_coroutine & operator=( push_coroutine && other) noexcept { if ( this != & other) { cb_ = other.cb_; other.cb_ = nullptr; @@ -71,33 +70,35 @@ public: push_coroutine< T > * c_; public: - iterator() : - c_( nullptr) { + iterator() noexcept : + c_{ nullptr } { } - explicit iterator( push_coroutine< T > * c) : - c_( c) { + explicit iterator( push_coroutine< T > * c) noexcept : + c_{ c } { } iterator & operator=( T t) { BOOST_ASSERT( c_); - if ( ! ( * c_)( t) ) c_ = 0; + if ( ! ( * c_)( t) ) { + c_ = nullptr; + } return * this; } - bool operator==( iterator const& other) const { + bool operator==( iterator const& other) const noexcept { return other.c_ == c_; } - bool operator!=( iterator const& other) const { + bool operator!=( iterator const& other) const noexcept { return other.c_ != c_; } - iterator & operator*() { + iterator & operator*() noexcept { return * this; } - iterator & operator++() { + iterator & operator++() noexcept { return * this; } }; @@ -113,23 +114,23 @@ private: control_block * cb_; - explicit push_coroutine( control_block *); + explicit push_coroutine( control_block *) noexcept; public: template< typename Fn > - explicit push_coroutine( Fn &&, bool = false); + explicit push_coroutine( Fn &&); template< typename StackAllocator, typename Fn > - explicit push_coroutine( StackAllocator, Fn &&, bool = false); + push_coroutine( StackAllocator, Fn &&); - ~push_coroutine(); + ~push_coroutine() noexcept; push_coroutine( push_coroutine const&) = delete; push_coroutine & operator=( push_coroutine const&) = delete; - push_coroutine( push_coroutine &&); + push_coroutine( push_coroutine &&) noexcept; - push_coroutine & operator=( push_coroutine && other) { + push_coroutine & operator=( push_coroutine && other) noexcept { if ( this != & other) { cb_ = other.cb_; other.cb_ = nullptr; @@ -148,33 +149,35 @@ public: push_coroutine< T & > * c_; public: - iterator() : - c_( nullptr) { + iterator() noexcept : + c_{ nullptr } { } - explicit iterator( push_coroutine< T & > * c) : - c_( c) { + explicit iterator( push_coroutine< T & > * c) noexcept : + c_{ c } { } iterator & operator=( T & t) { BOOST_ASSERT( c_); - if ( ! ( * c_)( t) ) c_ = 0; + if ( ! ( * c_)( t) ) { + c_ = nullptr; + } return * this; } - bool operator==( iterator const& other) const { + bool operator==( iterator const& other) const noexcept { return other.c_ == c_; } - bool operator!=( iterator const& other) const { + bool operator!=( iterator const& other) const noexcept { return other.c_ != c_; } - iterator & operator*() { + iterator & operator*() noexcept { return * this; } - iterator & operator++() { + iterator & operator++() noexcept { return * this; } }; @@ -190,23 +193,23 @@ private: control_block * cb_; - explicit push_coroutine( control_block *); + explicit push_coroutine( control_block *) noexcept; public: template< typename Fn > - explicit push_coroutine( Fn &&, bool = false); + explicit push_coroutine( Fn &&); template< typename StackAllocator, typename Fn > - explicit push_coroutine( StackAllocator, Fn &&, bool = false); + push_coroutine( StackAllocator, Fn &&); - ~push_coroutine(); + ~push_coroutine() noexcept; push_coroutine( push_coroutine const&) = delete; push_coroutine & operator=( push_coroutine const&) = delete; - push_coroutine( push_coroutine &&); + push_coroutine( push_coroutine &&) noexcept; - push_coroutine & operator=( push_coroutine && other) { + push_coroutine & operator=( push_coroutine && other) noexcept { if ( this != & other) { cb_ = other.cb_; other.cb_ = nullptr; diff --git a/include/boost/coroutine2/detail/push_coroutine.ipp b/include/boost/coroutine2/detail/push_coroutine.ipp index 5f48178..0883cbe 100644 --- a/include/boost/coroutine2/detail/push_coroutine.ipp +++ b/include/boost/coroutine2/detail/push_coroutine.ipp @@ -7,16 +7,13 @@ #ifndef BOOST_COROUTINES2_DETAIL_PUSH_COROUTINE_IPP #define BOOST_COROUTINES2_DETAIL_PUSH_COROUTINE_IPP -#include #include #include #include -#include -#include - #include +#include #include #include @@ -31,51 +28,31 @@ namespace detail { // push_coroutine< T > template< typename T > -push_coroutine< T >::push_coroutine( control_block * cb) : - cb_( cb) { +push_coroutine< T >::push_coroutine( control_block * cb) noexcept : + cb_{ cb } { } template< typename T > template< typename Fn > -push_coroutine< T >::push_coroutine( Fn && fn, bool preserve_fpu) : - push_coroutine( default_stack(), std::forward< Fn >( fn), preserve_fpu) { +push_coroutine< T >::push_coroutine( Fn && fn) : + push_coroutine{ default_stack(), std::forward< Fn >( fn) } { } template< typename T > template< typename StackAllocator, typename Fn > -push_coroutine< T >::push_coroutine( StackAllocator salloc, Fn && fn, bool preserve_fpu) : - cb_( nullptr) { - context::stack_context sctx( salloc.allocate() ); - // reserve space for control structure -#if defined(BOOST_NO_CXX14_CONSTEXPR) || defined(BOOST_NO_CXX11_STD_ALIGN) - void * sp = static_cast< char * >( sctx.sp) - sizeof( control_block); - std::size_t size = sctx.size - sizeof( control_block); -#else - constexpr std::size_t func_alignment = 64; // alignof( control_block); - constexpr std::size_t func_size = sizeof( control_block); - // reserve space on stack - void * sp = static_cast< char * >( sctx.sp) - func_size - func_alignment; - // align sp pointer - std::size_t space = func_size + func_alignment; - sp = std::align( func_alignment, func_size, sp, space); - BOOST_ASSERT( nullptr != sp); - // calculate remaining size - std::size_t size = sctx.size - ( static_cast< char * >( sctx.sp) - static_cast< char * >( sp) ); -#endif - // placment new for control structure on coroutine stack - cb_= new ( sp) control_block( context::preallocated( sp, size, sctx), - salloc, std::forward< Fn >( fn), preserve_fpu); +push_coroutine< T >::push_coroutine( StackAllocator salloc, Fn && fn) : + cb_{ create_control_block< control_block >( salloc, std::forward< Fn >( fn) ) } { } template< typename T > -push_coroutine< T >::~push_coroutine() { +push_coroutine< T >::~push_coroutine() noexcept { if ( nullptr != cb_) { cb_->~control_block(); } } template< typename T > -push_coroutine< T >::push_coroutine( push_coroutine && other) : +push_coroutine< T >::push_coroutine( push_coroutine && other) noexcept : cb_( other.cb_) { other.cb_ = nullptr; } @@ -109,51 +86,31 @@ push_coroutine< T >::operator!() const noexcept { // push_coroutine< T & > template< typename T > -push_coroutine< T & >::push_coroutine( control_block * cb) : - cb_( cb) { +push_coroutine< T & >::push_coroutine( control_block * cb) noexcept : + cb_{ cb } { } template< typename T > template< typename Fn > -push_coroutine< T & >::push_coroutine( Fn && fn, bool preserve_fpu) : - push_coroutine( default_stack(), std::forward< Fn >( fn), preserve_fpu) { +push_coroutine< T & >::push_coroutine( Fn && fn) : + push_coroutine{ default_stack(), std::forward< Fn >( fn) } { } template< typename T > template< typename StackAllocator, typename Fn > -push_coroutine< T & >::push_coroutine( StackAllocator salloc, Fn && fn, bool preserve_fpu) : - cb_( nullptr) { - context::stack_context sctx( salloc.allocate() ); - // reserve space for control structure -#if defined(BOOST_NO_CXX14_CONSTEXPR) || defined(BOOST_NO_CXX11_STD_ALIGN) - void * sp = static_cast< char * >( sctx.sp) - sizeof( control_block); - std::size_t size = sctx.size - sizeof( control_block); -#else - constexpr std::size_t func_alignment = 64; // alignof( control_block); - constexpr std::size_t func_size = sizeof( control_block); - // reserve space on stack - void * sp = static_cast< char * >( sctx.sp) - func_size - func_alignment; - // align sp pointer - std::size_t space = func_size + func_alignment; - sp = std::align( func_alignment, func_size, sp, space); - BOOST_ASSERT( nullptr != sp); - // calculate remaining size - std::size_t size = sctx.size - ( static_cast< char * >( sctx.sp) - static_cast< char * >( sp) ); -#endif - // placment new for control structure on coroutine stack - cb_ = new ( sp) control_block( context::preallocated( sp, size, sctx), - salloc, std::forward< Fn >( fn), preserve_fpu); +push_coroutine< T & >::push_coroutine( StackAllocator salloc, Fn && fn) : + cb_{ create_control_block< control_block >( salloc, std::forward< Fn >( fn) ) } { } template< typename T > -push_coroutine< T & >::~push_coroutine() { +push_coroutine< T & >::~push_coroutine() noexcept { if ( nullptr != cb_) { cb_->~control_block(); } } template< typename T > -push_coroutine< T & >::push_coroutine( push_coroutine && other) : +push_coroutine< T & >::push_coroutine( push_coroutine && other) noexcept : cb_( other.cb_) { other.cb_ = nullptr; } @@ -180,49 +137,29 @@ push_coroutine< T & >::operator!() const noexcept { // push_coroutine< void > inline -push_coroutine< void >::push_coroutine( control_block * cb) : - cb_( cb) { +push_coroutine< void >::push_coroutine( control_block * cb) noexcept : + cb_{ cb } { } template< typename Fn > -push_coroutine< void >::push_coroutine( Fn && fn, bool preserve_fpu) : - push_coroutine( default_stack(), std::forward< Fn >( fn), preserve_fpu) { +push_coroutine< void >::push_coroutine( Fn && fn) : + push_coroutine{ default_stack(), std::forward< Fn >( fn) } { } template< typename StackAllocator, typename Fn > -push_coroutine< void >::push_coroutine( StackAllocator salloc, Fn && fn, bool preserve_fpu) : - cb_( nullptr) { - context::stack_context sctx( salloc.allocate() ); - // reserve space for control structure -#if defined(BOOST_NO_CXX14_CONSTEXPR) || defined(BOOST_NO_CXX11_STD_ALIGN) - void * sp = static_cast< char * >( sctx.sp) - sizeof( control_block); - std::size_t size = sctx.size - sizeof( control_block); -#else - constexpr std::size_t func_alignment = 64; // alignof( control_block); - constexpr std::size_t func_size = sizeof( control_block); - // reserve space on stack - void * sp = static_cast< char * >( sctx.sp) - func_size - func_alignment; - // align sp pointer - std::size_t space = func_size + func_alignment; - sp = std::align( func_alignment, func_size, sp, space); - BOOST_ASSERT( nullptr != sp); - // calculate remaining size - std::size_t size = sctx.size - ( static_cast< char * >( sctx.sp) - static_cast< char * >( sp) ); -#endif - // placment new for control structure on coroutine stack - cb_ = new ( sp) control_block( context::preallocated( sp, size, sctx), - salloc, std::forward< Fn >( fn), preserve_fpu); +push_coroutine< void >::push_coroutine( StackAllocator salloc, Fn && fn) : + cb_{ create_control_block< control_block >( salloc, std::forward< Fn >( fn) ) } { } inline -push_coroutine< void >::~push_coroutine() { +push_coroutine< void >::~push_coroutine() noexcept { if ( nullptr != cb_) { cb_->~control_block(); } } inline -push_coroutine< void >::push_coroutine( push_coroutine && other) : +push_coroutine< void >::push_coroutine( push_coroutine && other) noexcept : cb_( other.cb_) { other.cb_ = nullptr; } diff --git a/include/boost/coroutine2/detail/state.hpp b/include/boost/coroutine2/detail/state.hpp index 714548f..baf7489 100644 --- a/include/boost/coroutine2/detail/state.hpp +++ b/include/boost/coroutine2/detail/state.hpp @@ -23,11 +23,61 @@ namespace coroutines2 { namespace detail { enum class state_t : unsigned int { + none = 0, complete = 1 << 1, unwind = 1 << 2, early_exit = 1 << 3 }; + +inline +constexpr state_t +operator&( state_t l, state_t r) { + return static_cast< state_t >( + static_cast< unsigned int >( l) & static_cast< unsigned int >( r) ); +} + +inline +constexpr state_t +operator|( state_t l, state_t r) { + return static_cast< state_t >( + static_cast< unsigned int >( l) | static_cast< unsigned int >( r) ); +} + +inline +constexpr state_t +operator^( state_t l, state_t r) { + return static_cast< state_t >( + static_cast< unsigned int >( l) ^ static_cast< unsigned int >( r) ); +} + +inline +constexpr state_t +operator~( state_t l) { + return static_cast< state_t >( ~static_cast< unsigned int >( l) ); +} + +inline +state_t & +operator&=( state_t & l, state_t r) { + l = l & r; + return l; +} + +inline +state_t & +operator|=( state_t & l, state_t r) { + l = l | r; + return l; +} + +inline +state_t & +operator^=( state_t & l, state_t r) { + l = l ^ r; + return l; +} + }}} #ifdef BOOST_HAS_ABI_HEADERS diff --git a/performance/performance_create_protected.cpp b/performance/performance_create_protected.cpp index 3262e1f..7eefd5c 100644 --- a/performance/performance_create_protected.cpp +++ b/performance/performance_create_protected.cpp @@ -20,7 +20,6 @@ typedef boost::coroutines2::protected_fixedsize_stack stack_allocator; typedef boost::coroutines2::coroutine< void > coro_type; -bool preserve = false; boost::uint64_t jobs = 1000; void fn( coro_type::pull_type & c) @@ -32,7 +31,7 @@ duration_type measure_time( duration_type overhead) time_point_type start( clock_type::now() ); for ( std::size_t i = 0; i < jobs; ++i) { - coro_type::push_type c( stack_alloc, fn, preserve); + coro_type::push_type c( stack_alloc, fn); } duration_type total = clock_type::now() - start; total -= overhead_clock(); // overhead of measurement @@ -48,7 +47,7 @@ cycle_type measure_cycles( cycle_type overhead) cycle_type start( cycles() ); for ( std::size_t i = 0; i < jobs; ++i) { - coro_type::push_type c( stack_alloc, fn, preserve); + coro_type::push_type c( stack_alloc, fn); } cycle_type total = cycles() - start; total -= overhead; // overhead of measurement @@ -67,7 +66,6 @@ int main( int argc, char * argv[]) desc.add_options() ("help", "help message") ("bind,b", boost::program_options::value< bool >( & bind), "bind thread to CPU") - ("fpu,f", boost::program_options::value< bool >( & preserve), "preserve FPU registers") ("jobs,j", boost::program_options::value< boost::uint64_t >( & jobs), "jobs to run"); boost::program_options::variables_map vm; diff --git a/performance/performance_create_standard.cpp b/performance/performance_create_standard.cpp index 58c1ce4..89652b0 100644 --- a/performance/performance_create_standard.cpp +++ b/performance/performance_create_standard.cpp @@ -20,7 +20,6 @@ typedef boost::coroutines2::fixedsize_stack stack_allocator; typedef boost::coroutines2::coroutine< void > coro_type; -bool preserve = false; boost::uint64_t jobs = 1000; void fn( coro_type::pull_type & c) @@ -32,7 +31,7 @@ duration_type measure_time( duration_type overhead) time_point_type start( clock_type::now() ); for ( std::size_t i = 0; i < jobs; ++i) { - coro_type::push_type c( stack_alloc, fn, preserve); + coro_type::push_type c( stack_alloc, fn); } duration_type total = clock_type::now() - start; total -= overhead_clock(); // overhead of measurement @@ -48,7 +47,7 @@ cycle_type measure_cycles( cycle_type overhead) cycle_type start( cycles() ); for ( std::size_t i = 0; i < jobs; ++i) { - coro_type::push_type c( stack_alloc, fn, preserve); + coro_type::push_type c( stack_alloc, fn); } cycle_type total = cycles() - start; total -= overhead; // overhead of measurement @@ -67,7 +66,6 @@ int main( int argc, char * argv[]) desc.add_options() ("help", "help message") ("bind,b", boost::program_options::value< bool >( & bind), "bind thread to CPU") - ("fpu,f", boost::program_options::value< bool >( & preserve), "preserve FPU registers") ("jobs,j", boost::program_options::value< boost::uint64_t >( & jobs), "jobs to run"); boost::program_options::variables_map vm; diff --git a/performance/performance_switch.cpp b/performance/performance_switch.cpp index 41b6ab0..e8be826 100644 --- a/performance/performance_switch.cpp +++ b/performance/performance_switch.cpp @@ -18,7 +18,6 @@ #include "clock.hpp" #include "cycle.hpp" -bool preserve = false; boost::uint64_t jobs = 1000; struct X @@ -45,7 +44,7 @@ void fn_x( boost::coroutines2::coroutine< X >::push_type & c) duration_type measure_time_void( duration_type overhead) { - boost::coroutines2::coroutine< void >::pull_type c( fn_void, preserve); + boost::coroutines2::coroutine< void >::pull_type c( fn_void); time_point_type start( clock_type::now() ); for ( std::size_t i = 0; i < jobs; ++i) { @@ -61,7 +60,7 @@ duration_type measure_time_void( duration_type overhead) duration_type measure_time_int( duration_type overhead) { - boost::coroutines2::coroutine< int >::pull_type c( fn_int, preserve); + boost::coroutines2::coroutine< int >::pull_type c( fn_int); time_point_type start( clock_type::now() ); for ( std::size_t i = 0; i < jobs; ++i) { @@ -77,7 +76,7 @@ duration_type measure_time_int( duration_type overhead) duration_type measure_time_x( duration_type overhead) { - boost::coroutines2::coroutine< X >::pull_type c( fn_x, preserve); + boost::coroutines2::coroutine< X >::pull_type c( fn_x); time_point_type start( clock_type::now() ); for ( std::size_t i = 0; i < jobs; ++i) { @@ -94,7 +93,7 @@ duration_type measure_time_x( duration_type overhead) # ifdef BOOST_CONTEXT_CYCLE cycle_type measure_cycles_void( cycle_type overhead) { - boost::coroutines2::coroutine< void >::pull_type c( fn_void, preserve); + boost::coroutines2::coroutine< void >::pull_type c( fn_void); cycle_type start( cycles() ); for ( std::size_t i = 0; i < jobs; ++i) { @@ -110,7 +109,7 @@ cycle_type measure_cycles_void( cycle_type overhead) cycle_type measure_cycles_int( cycle_type overhead) { - boost::coroutines2::coroutine< int >::pull_type c( fn_int, preserve); + boost::coroutines2::coroutine< int >::pull_type c( fn_int); cycle_type start( cycles() ); for ( std::size_t i = 0; i < jobs; ++i) { @@ -126,7 +125,7 @@ cycle_type measure_cycles_int( cycle_type overhead) cycle_type measure_cycles_x( cycle_type overhead) { - boost::coroutines2::coroutine< X >::pull_type c( fn_x, preserve); + boost::coroutines2::coroutine< X >::pull_type c( fn_x); cycle_type start( cycles() ); for ( std::size_t i = 0; i < jobs; ++i) { @@ -150,7 +149,6 @@ int main( int argc, char * argv[]) desc.add_options() ("help", "help message") ("bind,b", boost::program_options::value< bool >( & bind), "bind thread to CPU") - ("fpu,f", boost::program_options::value< bool >( & preserve), "preserve FPU registers") ("jobs,j", boost::program_options::value< boost::uint64_t >( & jobs), "jobs to run"); boost::program_options::variables_map vm; diff --git a/performance/segmented/performance_create_segmented.cpp b/performance/segmented/performance_create_segmented.cpp index f0d1e30..d2313bf 100644 --- a/performance/segmented/performance_create_segmented.cpp +++ b/performance/segmented/performance_create_segmented.cpp @@ -20,7 +20,6 @@ typedef boost::coroutines2::segmented_stack stack_allocator; typedef boost::coroutines2::coroutine< void > coro_type; -bool preserve = false; boost::uint64_t jobs = 1000; void fn( coro_type::push_type & c) @@ -32,7 +31,7 @@ duration_type measure_time( duration_type overhead) time_point_type start( clock_type::now() ); for ( std::size_t i = 0; i < jobs; ++i) { - coro_type::pull_type c( stack_alloc, fn, preserve); + coro_type::pull_type c( stack_alloc, fn); } duration_type total = clock_type::now() - start; total -= overhead_clock(); // overhead of measurement @@ -48,7 +47,7 @@ cycle_type measure_cycles( cycle_type overhead) cycle_type start( cycles() ); for ( std::size_t i = 0; i < jobs; ++i) { - coro_type::pull_type c( stack_alloc, fn, preserve); + coro_type::pull_type c( stack_alloc, fn); } cycle_type total = cycles() - start; total -= overhead; // overhead of measurement @@ -62,12 +61,11 @@ int main( int argc, char * argv[]) { try { - bool preserve = false, unwind = true, bind = false; + bool bind = false; boost::program_options::options_description desc("allowed options"); desc.add_options() ("help", "help message") ("bind,b", boost::program_options::value< bool >( & bind), "bind thread to CPU") - ("fpu,f", boost::program_options::value< bool >( & preserve), "preserve FPU registers") ("jobs,j", boost::program_options::value< boost::uint64_t >( & jobs), "jobs to run"); boost::program_options::variables_map vm; diff --git a/performance/segmented/performance_switch.cpp b/performance/segmented/performance_switch.cpp index 828c004..b23c1e2 100644 --- a/performance/segmented/performance_switch.cpp +++ b/performance/segmented/performance_switch.cpp @@ -18,7 +18,6 @@ #include "../clock.hpp" #include "../cycle.hpp" -bool preserve = false; boost::uint64_t jobs = 1000; struct X @@ -46,7 +45,7 @@ void fn_x( boost::coroutines2::coroutine< X >::push_type & c) duration_type measure_time_void( duration_type overhead) { boost::coroutines2::segmented_stack stack_alloc; - boost::coroutines2::coroutine< void >::pull_type c( stack_alloc, fn_void, preserve); + boost::coroutines2::coroutine< void >::pull_type c( stack_alloc, fn_void); time_point_type start( clock_type::now() ); for ( std::size_t i = 0; i < jobs; ++i) { @@ -63,7 +62,7 @@ duration_type measure_time_void( duration_type overhead) duration_type measure_time_int( duration_type overhead) { boost::coroutines2::segmented_stack stack_alloc; - boost::coroutines2::coroutine< int >::pull_type c( stack_alloc, fn_int, preserve); + boost::coroutines2::coroutine< int >::pull_type c( stack_alloc, fn_int); time_point_type start( clock_type::now() ); for ( std::size_t i = 0; i < jobs; ++i) { @@ -80,7 +79,7 @@ duration_type measure_time_int( duration_type overhead) duration_type measure_time_x( duration_type overhead) { boost::coroutines2::segmented_stack stack_alloc; - boost::coroutines2::coroutine< X >::pull_type c( stack_alloc, fn_x, preserve); + boost::coroutines2::coroutine< X >::pull_type c( stack_alloc, fn_x); time_point_type start( clock_type::now() ); for ( std::size_t i = 0; i < jobs; ++i) { @@ -98,7 +97,7 @@ duration_type measure_time_x( duration_type overhead) cycle_type measure_cycles_void( cycle_type overhead) { boost::coroutines2::segmented_stack stack_alloc; - boost::coroutines2::coroutine< void >::pull_type c( stack_alloc, fn_void, preserve); + boost::coroutines2::coroutine< void >::pull_type c( stack_alloc, fn_void); cycle_type start( cycles() ); for ( std::size_t i = 0; i < jobs; ++i) { @@ -115,7 +114,7 @@ cycle_type measure_cycles_void( cycle_type overhead) cycle_type measure_cycles_int( cycle_type overhead) { boost::coroutines2::segmented_stack stack_alloc; - boost::coroutines2::coroutine< int >::pull_type c( stack_alloc, fn_int, preserve); + boost::coroutines2::coroutine< int >::pull_type c( stack_alloc, fn_int); cycle_type start( cycles() ); for ( std::size_t i = 0; i < jobs; ++i) { @@ -132,7 +131,7 @@ cycle_type measure_cycles_int( cycle_type overhead) cycle_type measure_cycles_x( cycle_type overhead) { boost::coroutines2::segmented_stack stack_alloc; - boost::coroutines2::coroutine< X >::pull_type c( stack_alloc, fn_x, preserve); + boost::coroutines2::coroutine< X >::pull_type c( stack_alloc, fn_x); cycle_type start( cycles() ); for ( std::size_t i = 0; i < jobs; ++i) { @@ -156,7 +155,6 @@ int main( int argc, char * argv[]) desc.add_options() ("help", "help message") ("bind,b", boost::program_options::value< bool >( & bind), "bind thread to CPU") - ("fpu,f", boost::program_options::value< bool >( & preserve), "preserve FPU registers") ("jobs,j", boost::program_options::value< boost::uint64_t >( & jobs), "jobs to run"); boost::program_options::variables_map vm;