diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2016-10-06 10:30:07 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2016-10-06 10:32:57 +0900 |
commit | 71d216b90256936a9638f325af9bc69d720e75de (patch) | |
tree | 9c5f682d341c7c88ad0c8e3d4b262e00b6fb691a /boost/context/execution_context.hpp | |
parent | 733b5d5ae2c5d625211e2985ac25728ac3f54883 (diff) | |
download | boost-71d216b90256936a9638f325af9bc69d720e75de.tar.gz boost-71d216b90256936a9638f325af9bc69d720e75de.tar.bz2 boost-71d216b90256936a9638f325af9bc69d720e75de.zip |
Imported Upstream version 1.59.0
Change-Id: I2dde00f4eca71df3eea9d251dcaecde18a6c90a5
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
Diffstat (limited to 'boost/context/execution_context.hpp')
-rw-r--r-- | boost/context/execution_context.hpp | 304 |
1 files changed, 4 insertions, 300 deletions
diff --git a/boost/context/execution_context.hpp b/boost/context/execution_context.hpp index 4d809b0c21..97b1d4e70a 100644 --- a/boost/context/execution_context.hpp +++ b/boost/context/execution_context.hpp @@ -4,304 +4,8 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#ifndef BOOST_CONTEXT_EXECUTION_CONTEXT_H -#define BOOST_CONTEXT_EXECUTION_CONTEXT_H - -#include <boost/context/detail/config.hpp> - -#if ! defined(BOOST_CONTEXT_NO_EXECUTION_CONTEXT) - -# include <cstddef> -# include <cstdint> -# include <cstdlib> -# include <exception> -# include <memory> -# include <tuple> -# include <utility> - -# include <boost/assert.hpp> -# include <boost/config.hpp> -# include <boost/context/fcontext.hpp> -# include <boost/intrusive_ptr.hpp> - -# include <boost/context/stack_context.hpp> -# include <boost/context/segmented_stack.hpp> - -# ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -# endif - -# if defined(BOOST_USE_SEGMENTED_STACKS) -extern "C" { - -void __splitstack_getcontext( void * [BOOST_CONTEXT_SEGMENTS]); - -void __splitstack_setcontext( void * [BOOST_CONTEXT_SEGMENTS]); - -} -# endif - -namespace boost { -namespace context { - -struct preallocated { - void * sp; - std::size_t size; - stack_context sctx; - - preallocated( void * sp_, std::size_t size_, stack_context sctx_) noexcept : - sp( sp_), size( size_), sctx( sctx_) { - } -}; - -class BOOST_CONTEXT_DECL execution_context { -private: - struct fcontext { - std::size_t use_count; - fcontext_t fctx; - stack_context sctx; - - // main-context - fcontext() noexcept : - use_count( 1), - fctx( nullptr), - sctx() { - } - - // worker-context - fcontext( fcontext_t fctx_, stack_context const& sctx_) noexcept : - use_count( 0), - fctx( fctx_), - sctx( sctx_) { - } - - virtual ~fcontext() noexcept { - } - - virtual void deallocate() { - } - - virtual void run() noexcept { - } - - friend void intrusive_ptr_add_ref( fcontext * ctx) { - ++ctx->use_count; - } - - friend void intrusive_ptr_release( fcontext * ctx) { - BOOST_ASSERT( nullptr != ctx); - - if ( 0 == --ctx->use_count) { - ctx->~fcontext(); - } - } - }; - - template< typename Fn, typename StackAlloc > - class worker_fcontext : public fcontext { - private: - StackAlloc salloc_; - Fn fn_; - - static void destroy( worker_fcontext * p) { - StackAlloc salloc( p->salloc_); - stack_context sctx( p->sctx); - p->~worker_fcontext(); - salloc.deallocate( sctx); - } - - public: - explicit worker_fcontext( stack_context sctx, StackAlloc const& salloc, fcontext_t fctx, Fn && fn) noexcept : - fcontext( fctx, sctx), - salloc_( salloc), - fn_( std::forward< Fn >( fn) ) { - } - - void deallocate() override final { - destroy( this); - } - - void run() noexcept override final { - fn_(); - } - }; - - static void entry_func( intptr_t p) noexcept { - BOOST_ASSERT( 0 != p); - - fcontext * bp( reinterpret_cast< fcontext * >( p) ); - BOOST_ASSERT( nullptr != bp); - - bp->run(); - } - - typedef boost::intrusive_ptr< fcontext > ptr_t; - - thread_local static fcontext main_ctx_; - thread_local static ptr_t current_ctx_; - - boost::intrusive_ptr< fcontext > ptr_; -# if defined(BOOST_USE_SEGMENTED_STACKS) - bool use_segmented_stack_ = false; -# endif - - template< typename StackAlloc, typename Fn > - static fcontext * create_context( StackAlloc salloc, Fn && fn) { - typedef worker_fcontext< Fn, StackAlloc > func_t; - - stack_context sctx( salloc.allocate() ); - // reserve space for control structure - std::size_t size = sctx.size - sizeof( func_t); - void * sp = static_cast< char * >( sctx.sp) - sizeof( func_t); -#if 0 - constexpr std::size_t func_alignment = 64; // alignof( func_t); - constexpr std::size_t func_size = sizeof( func_t); - // reserve space on stack - void * sp = static_cast< char * >( sctx.sp) - func_size - func_alignment; - // align sp pointer - sp = std::align( func_alignment, func_size, sp, func_size + func_alignment); - BOOST_ASSERT( nullptr != sp); - // calculate remaining size - std::size_t size = sctx.size - ( static_cast< char * >( sctx.sp) - static_cast< char * >( sp) ); -#endif - // create fast-context - fcontext_t fctx = make_fcontext( sp, size, & execution_context::entry_func); - BOOST_ASSERT( nullptr != fctx); - // placment new for control structure on fast-context stack - return new ( sp) func_t( sctx, salloc, fctx, std::forward< Fn >( fn) ); - } - - template< typename StackAlloc, typename Fn > - static fcontext * create_context( preallocated palloc, StackAlloc salloc, Fn && fn) { - typedef worker_fcontext< Fn, StackAlloc > func_t; - - // reserve space for control structure - std::size_t size = palloc.size - sizeof( func_t); - void * sp = static_cast< char * >( palloc.sp) - sizeof( func_t); -#if 0 - constexpr std::size_t func_alignment = 64; // alignof( func_t); - constexpr std::size_t func_size = sizeof( func_t); - // reserve space on stack - void * sp = static_cast< char * >( palloc.sp) - func_size - func_alignment; - // align sp pointer - sp = std::align( func_alignment, func_size, sp, func_size + func_alignment); - BOOST_ASSERT( nullptr != sp); - // calculate remaining size - std::size_t size = palloc.size - ( static_cast< char * >( palloc.sp) - static_cast< char * >( sp) ); +#if defined(BOOST_USE_WINFIBERS) +#include <boost/context/execution_context_winfib.ipp> +#else +#include <boost/context/execution_context.ipp> #endif - // create fast-context - fcontext_t fctx = make_fcontext( sp, size, & execution_context::entry_func); - BOOST_ASSERT( nullptr != fctx); - // placment new for control structure on fast-context stack - return new ( sp) func_t( palloc.sctx, salloc, fctx, std::forward< Fn >( fn) ); - } - - template< typename StackAlloc, typename Fn, typename Tpl, std::size_t ... I > - static fcontext * create_worker_fcontext( StackAlloc salloc, - Fn && fn_, Tpl && tpl_, - std::index_sequence< I ... >) { - return create_context( salloc, - [fn=std::forward< Fn >( fn_),tpl=std::forward< Tpl >( tpl_)] () mutable { - try { - fn( - // std::tuple_element<> does not perfect forwarding - std::forward< decltype( std::get< I >( std::declval< Tpl >() ) ) >( - std::get< I >( std::forward< Tpl >( tpl) ) ) ... ); - } catch (...) { - std::terminate(); - } - }); - } - - template< typename StackAlloc, typename Fn, typename Tpl, std::size_t ... I > - static fcontext * create_worker_fcontext( preallocated palloc, StackAlloc salloc, - Fn && fn_, Tpl && tpl_, - std::index_sequence< I ... >) { - return create_context( palloc, salloc, - [fn=std::forward< Fn >( fn_),tpl=std::forward< Tpl >( tpl_)] () mutable { - try { - fn( - // std::tuple_element<> does not perfect forwarding - std::forward< decltype( std::get< I >( std::declval< Tpl >() ) ) >( - std::get< I >( std::forward< Tpl >( tpl) ) ) ... ); - } catch (...) { - std::terminate(); - } - }); - } - - execution_context() : - ptr_( current_ctx_) { - } - -public: - static execution_context current() noexcept { - return execution_context(); - } - -# if defined(BOOST_USE_SEGMENTED_STACKS) - template< typename Fn, typename ... Args > - explicit execution_context( segmented_stack salloc, Fn && fn, Args && ... args) : - ptr_( create_worker_fcontext( salloc, - std::forward< Fn >( fn), - std::make_tuple( std::forward< Args >( args) ... ), - std::index_sequence_for< Args ... >() ) ), - use_segmented_stack_( true) { - } - - template< typename Fn, typename ... Args > - explicit execution_context( preallocated palloc, segmented_stack salloc, Fn && fn, Args && ... args) : - ptr_( create_worker_fcontext( palloc, salloc, - std::forward< Fn >( fn), - std::make_tuple( std::forward< Args >( args) ... ), - std::index_sequence_for< Args ... >() ) ), - use_segmented_stack_( true) { - } -# endif - - template< typename StackAlloc, typename Fn, typename ... Args > - explicit execution_context( StackAlloc salloc, Fn && fn, Args && ... args) : - ptr_( create_worker_fcontext( salloc, - std::forward< Fn >( fn), - std::make_tuple( std::forward< Args >( args) ... ), - std::index_sequence_for< Args ... >() ) ) { - } - - template< typename StackAlloc, typename Fn, typename ... Args > - explicit execution_context( preallocated palloc, StackAlloc salloc, Fn && fn, Args && ... args) : - ptr_( create_worker_fcontext( palloc, salloc, - std::forward< Fn >( fn), - std::make_tuple( std::forward< Args >( args) ... ), - std::index_sequence_for< Args ... >() ) ) { - } - - void resume( bool preserve_fpu = false) noexcept { - fcontext * old_ctx( current_ctx_.get() ); - fcontext * new_ctx( ptr_.get() ); - current_ctx_ = ptr_; -# if defined(BOOST_USE_SEGMENTED_STACKS) - if ( use_segmented_stack_) { - __splitstack_getcontext( old_ctx->sctx.segments_ctx); - __splitstack_setcontext( new_ctx->sctx.segments_ctx); - - jump_fcontext( & old_ctx->fctx, new_ctx->fctx, reinterpret_cast< intptr_t >( new_ctx), preserve_fpu); - - __splitstack_setcontext( old_ctx->sctx.segments_ctx); - } else { - jump_fcontext( & old_ctx->fctx, new_ctx->fctx, reinterpret_cast< intptr_t >( new_ctx), preserve_fpu); - } -# else - jump_fcontext( & old_ctx->fctx, new_ctx->fctx, reinterpret_cast< intptr_t >( new_ctx), preserve_fpu); -# endif - } -}; - -}} - -# ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -# endif - -#endif - -#endif // BOOST_CONTEXT_EXECUTION_CONTEXT_H |