BVB Source Codes

mars Show execution_context_v2.hpp Source code

Return Download mars: download execution_context_v2.hpp Source code - Download mars Source code - Type:.hpp
  1.  
  2. //          Copyright Oliver Kowalke 2014.
  3. // Distributed under the Boost Software License, Version 1.0.
  4. //    (See accompanying file LICENSE_1_0.txt or copy at
  5. //          http://www.boost.org/LICENSE_1_0.txt)
  6.  
  7. #ifndef BOOST_CONTEXT_EXECUTION_CONTEXT_H
  8. #define BOOST_CONTEXT_EXECUTION_CONTEXT_H
  9.  
  10. #include <boost/context/detail/config.hpp>
  11.  
  12. #include <algorithm>
  13. #include <cstddef>
  14. #include <cstdint>
  15. #include <cstdlib>
  16. #include <functional>
  17. #include <memory>
  18. #include <ostream>
  19. #include <tuple>
  20. #include <utility>
  21.  
  22. #include <boost/assert.hpp>
  23. #include <boost/config.hpp>
  24. #include <boost/intrusive_ptr.hpp>
  25.  
  26. #include <boost/context/detail/apply.hpp>
  27. #include <boost/context/detail/disable_overload.hpp>
  28. #include <boost/context/detail/exception.hpp>
  29. #include <boost/context/detail/exchange.hpp>
  30. #include <boost/context/detail/fcontext.hpp>
  31. #include <boost/context/detail/tuple.hpp>
  32. #include <boost/context/fixedsize_stack.hpp>
  33. #include <boost/context/flags.hpp>
  34. #include <boost/context/preallocated.hpp>
  35. #include <boost/context/segmented_stack.hpp>
  36. #include <boost/context/stack_context.hpp>
  37.  
  38. #ifdef BOOST_HAS_ABI_HEADERS
  39. # include BOOST_ABI_PREFIX
  40. #endif
  41.  
  42. namespace mars_boost {} namespace boost = mars_boost; namespace mars_boost {
  43. namespace context {
  44. namespace detail {
  45.  
  46. inline
  47. transfer_t context_unwind( transfer_t t) {
  48.     throw forced_unwind( t.fctx);
  49.     return { nullptr, nullptr };
  50. }
  51.  
  52. template< typename Rec >
  53. transfer_t context_exit( transfer_t t) noexcept {
  54.     Rec * rec = static_cast< Rec * >( t.data);
  55.     // destroy context stack
  56.     rec->deallocate();
  57.     return { nullptr, nullptr };
  58. }
  59.  
  60. template< typename Rec >
  61. void context_entry( transfer_t t_) noexcept {
  62.     // transfer control structure to the context-stack
  63.     Rec * rec = static_cast< Rec * >( t_.data);
  64.     BOOST_ASSERT( nullptr != rec);
  65.     transfer_t t = { nullptr, nullptr };
  66.     try {
  67.         // jump back to `context_create()`
  68.         t = jump_fcontext( t_.fctx, nullptr);
  69.         // start executing
  70.         t = rec->run( t);
  71.     } catch ( forced_unwind const& e) {
  72.         t = { e.fctx, nullptr };
  73.     }
  74.     BOOST_ASSERT( nullptr != t.fctx);
  75.     // destroy context-stack of `this`context on next context
  76.     ontop_fcontext( t.fctx, rec, context_exit< Rec >);
  77.     BOOST_ASSERT_MSG( false, "context already terminated");
  78. }
  79.  
  80. template< typename Ctx, typename Fn, typename ... Args >
  81. transfer_t context_ontop( transfer_t t) {
  82.     auto tpl = static_cast< std::tuple< Fn, std::tuple< Args ... > > * >( t.data);
  83.     BOOST_ASSERT( nullptr != tpl);
  84.     typename std::decay< Fn >::type fn = std::forward< Fn >( std::get< 0 >( * tpl) );
  85.     auto args = std::move( std::get< 1 >( * tpl) );
  86.     Ctx ctx{ t.fctx };
  87.     // execute function
  88.     auto result = apply(
  89.             fn,
  90.             std::tuple_cat(
  91.                 std::forward_as_tuple( std::move( ctx) ),
  92.                 std::move( args) ) );
  93.     ctx = std::move( std::get< 0 >( result) );
  94.     // apply returned data
  95.     detail::tail( args) = std::move( result);
  96.     std::get< 1 >( * tpl) = std::move( args);
  97.     return { exchange( ctx.fctx_, nullptr), & std::get< 1 >( * tpl) };
  98. }
  99.  
  100. template< typename Ctx, typename StackAlloc, typename Fn, typename ... Params >
  101. class record {
  102. private:
  103.     StackAlloc                                          salloc_;
  104.     stack_context                                       sctx_;
  105.     typename std::decay< Fn >::type                     fn_;
  106.     std::tuple< typename std::decay< Params >::type ... > params_;
  107.  
  108.     static void destroy( record * p) noexcept {
  109.         StackAlloc salloc = p->salloc_;
  110.         stack_context sctx = p->sctx_;
  111.         // deallocate record
  112.         p->~record();
  113.         // destroy stack with stack allocator
  114.         salloc.deallocate( sctx);
  115.     }
  116.  
  117. public:
  118.     record( stack_context sctx, StackAlloc const& salloc,
  119.             Fn && fn, Params && ... params) noexcept :
  120.         salloc_( salloc),
  121.         sctx_( sctx),
  122.         fn_( std::forward< Fn >( fn) ),
  123.         params_( std::forward< Params >( params) ... ) {
  124.     }
  125.  
  126.     record( record const&) = delete;
  127.     record & operator=( record const&) = delete;
  128.  
  129.     void deallocate() noexcept {
  130.         destroy( this);
  131.     }
  132.  
  133.     transfer_t run( transfer_t t) {
  134.         Ctx from{ t.fctx };
  135.         typename Ctx::args_tpl_t args = std::move( * static_cast< typename Ctx::args_tpl_t * >( t.data) );
  136.         auto tpl = std::tuple_cat(
  137.                     params_,
  138.                     std::forward_as_tuple( std::move( from) ),
  139.                     std::move( args) );
  140.         // invoke context-function
  141.         Ctx cc = apply( std::move( fn_), std::move( tpl) );
  142.         return { exchange( cc.fctx_, nullptr), nullptr };
  143.     }
  144. };
  145.  
  146. template< typename Ctx, typename StackAlloc, typename Fn, typename ... Params >
  147. fcontext_t context_create( StackAlloc salloc, Fn && fn, Params && ... params) {
  148.     typedef record< Ctx, StackAlloc, Fn, Params ... >  record_t;
  149.  
  150.     auto sctx = salloc.allocate();
  151.     // reserve space for control structure
  152. #if defined(BOOST_NO_CXX11_CONSTEXPR) || defined(BOOST_NO_CXX11_STD_ALIGN)
  153.     const std::size_t size = sctx.size - sizeof( record_t);
  154.     void * sp = static_cast< char * >( sctx.sp) - sizeof( record_t);
  155. #else
  156.     constexpr std::size_t func_alignment = 64; // alignof( record_t);
  157.     constexpr std::size_t func_size = sizeof( record_t);
  158.     // reserve space on stack
  159.     void * sp = static_cast< char * >( sctx.sp) - func_size - func_alignment;
  160.     // align sp pointer
  161.     std::size_t space = func_size + func_alignment;
  162.     sp = std::align( func_alignment, func_size, sp, space);
  163.     BOOST_ASSERT( nullptr != sp);
  164.     // calculate remaining size
  165.     const std::size_t size = sctx.size - ( static_cast< char * >( sctx.sp) - static_cast< char * >( sp) );
  166. #endif
  167.     // create fast-context
  168.     const fcontext_t fctx = make_fcontext( sp, size, & context_entry< record_t >);
  169.     BOOST_ASSERT( nullptr != fctx);
  170.     // placment new for control structure on context-stack
  171.     auto rec = ::new ( sp) record_t{
  172.             sctx, salloc, std::forward< Fn >( fn), std::forward< Params >( params) ... };
  173.     // transfer control structure to context-stack
  174.     return jump_fcontext( fctx, rec).fctx;
  175. }
  176.  
  177. template< typename Ctx, typename StackAlloc, typename Fn, typename ... Params >
  178. fcontext_t context_create( preallocated palloc, StackAlloc salloc, Fn && fn, Params && ... params) {
  179.     typedef record< Ctx, StackAlloc, Fn, Params ... >  record_t;
  180.  
  181.     // reserve space for control structure
  182. #if defined(BOOST_NO_CXX11_CONSTEXPR) || defined(BOOST_NO_CXX11_STD_ALIGN)
  183.     const std::size_t size = palloc.size - sizeof( record_t);
  184.     void * sp = static_cast< char * >( palloc.sp) - sizeof( record_t);
  185. #else
  186.     constexpr std::size_t func_alignment = 64; // alignof( record_t);
  187.     constexpr std::size_t func_size = sizeof( record_t);
  188.     // reserve space on stack
  189.     void * sp = static_cast< char * >( palloc.sp) - func_size - func_alignment;
  190.     // align sp pointer
  191.     std::size_t space = func_size + func_alignment;
  192.     sp = std::align( func_alignment, func_size, sp, space);
  193.     BOOST_ASSERT( nullptr != sp);
  194.     // calculate remaining size
  195.     const std::size_t size = palloc.size - ( static_cast< char * >( palloc.sp) - static_cast< char * >( sp) );
  196. #endif
  197.     // create fast-context
  198.     const fcontext_t fctx = make_fcontext( sp, size, & context_entry< record_t >);
  199.     BOOST_ASSERT( nullptr != fctx);
  200.     // placment new for control structure on context-stack
  201.     auto rec = ::new ( sp) record_t{
  202.             palloc.sctx, salloc, std::forward< Fn >( fn), std::forward< Params >( params) ... };
  203.     // transfer control structure to context-stack
  204.     return jump_fcontext( fctx, rec).fctx;
  205. }
  206.  
  207. }
  208.  
  209. template< typename ... Args >
  210. class execution_context {
  211. private:
  212.     typedef std::tuple< Args ... >     args_tpl_t;
  213.     typedef std::tuple< execution_context, typename std::decay< Args >::type ... >               ret_tpl_t;
  214.  
  215.     template< typename Ctx, typename StackAlloc, typename Fn, typename ... Params >
  216.     friend class detail::record;
  217.  
  218.     template< typename Ctx, typename Fn, typename ... ArgsT >
  219.     friend detail::transfer_t detail::context_ontop( detail::transfer_t);
  220.  
  221.     detail::fcontext_t  fctx_{ nullptr };
  222.  
  223.     execution_context( detail::fcontext_t fctx) noexcept :
  224.         fctx_( fctx) {
  225.     }
  226.  
  227. public:
  228.     constexpr execution_context() noexcept = default;
  229.  
  230. #if defined(BOOST_USE_SEGMENTED_STACKS)
  231.     // segmented-stack requires to preserve the segments of the `current` context
  232.     // which is not possible (no global pointer to current context)
  233.     template< typename Fn, typename ... Params >
  234.     execution_context( std::allocator_arg_t, segmented_stack, Fn &&, Params && ...) = delete;
  235.  
  236.     template< typename Fn, typename ... Params >
  237.     execution_context( std::allocator_arg_t, preallocated, segmented_stack, Fn &&, Params && ...) = delete;
  238. #else
  239.     template< typename Fn,
  240.               typename ... Params,
  241.               typename = detail::disable_overload< execution_context, Fn >
  242.     >
  243.     execution_context( Fn && fn, Params && ... params) :
  244.         // deferred execution of fn and its arguments
  245.         // arguments are stored in std::tuple<>
  246.         // non-type template parameter pack via std::index_sequence_for<>
  247.         // preserves the number of arguments
  248.         // used to extract the function arguments from std::tuple<>
  249.         fctx_( detail::context_create< execution_context >(
  250.                     fixedsize_stack(),
  251.                     std::forward< Fn >( fn),
  252.                     std::forward< Params >( params) ... ) ) {
  253.     }
  254.  
  255.     template< typename StackAlloc,
  256.               typename Fn,
  257.               typename ... Params
  258.     >
  259.     execution_context( std::allocator_arg_t, StackAlloc salloc, Fn && fn, Params && ... params) :
  260.         // deferred execution of fn and its arguments
  261.         // arguments are stored in std::tuple<>
  262.         // non-type template parameter pack via std::index_sequence_for<>
  263.         // preserves the number of arguments
  264.         // used to extract the function arguments from std::tuple<>
  265.         fctx_( detail::context_create< execution_context >(
  266.                     salloc,
  267.                     std::forward< Fn >( fn),
  268.                     std::forward< Params >( params) ... ) ) {
  269.     }
  270.  
  271.     template< typename StackAlloc,
  272.               typename Fn,
  273.               typename ... Params
  274.     >
  275.     execution_context( std::allocator_arg_t, preallocated palloc, StackAlloc salloc, Fn && fn, Params && ... params) :
  276.         // deferred execution of fn and its arguments
  277.         // arguments are stored in std::tuple<>
  278.         // non-type template parameter pack via std::index_sequence_for<>
  279.         // preserves the number of arguments
  280.         // used to extract the function arguments from std::tuple<>
  281.         fctx_( detail::context_create< execution_context >(
  282.                     palloc, salloc,
  283.                     std::forward< Fn >( fn),
  284.                     std::forward< Params >( params) ... ) ) {
  285.     }
  286. #endif
  287.  
  288.     ~execution_context() {
  289.         if ( nullptr != fctx_) {
  290.             detail::ontop_fcontext( detail::exchange( fctx_, nullptr), nullptr, detail::context_unwind);
  291.         }
  292.     }
  293.  
  294.     execution_context( execution_context && other) noexcept :
  295.         fctx_( other.fctx_) {
  296.         other.fctx_ = nullptr;
  297.     }
  298.  
  299.     execution_context & operator=( execution_context && other) noexcept {
  300.         if ( this != & other) {
  301.             execution_context tmp = std::move( other);
  302.             swap( tmp);
  303.         }
  304.         return * this;
  305.     }
  306.  
  307.     execution_context( execution_context const& other) noexcept = delete;
  308.     execution_context & operator=( execution_context const& other) noexcept = delete;
  309.  
  310.     ret_tpl_t operator()( Args ... args) {
  311.         BOOST_ASSERT( nullptr != fctx_);
  312.         args_tpl_t data( std::forward< Args >( args) ... );
  313.         detail::transfer_t t = detail::jump_fcontext( detail::exchange( fctx_, nullptr), & data);
  314.         if ( nullptr != t.data) {
  315.             data = std::move( * static_cast< args_tpl_t * >( t.data) );
  316.         }
  317.         return std::tuple_cat( std::forward_as_tuple( execution_context( t.fctx) ), std::move( data) );
  318.     }
  319.  
  320.     template< typename Fn >
  321.     ret_tpl_t operator()( exec_ontop_arg_t, Fn && fn, Args ... args) {
  322.         BOOST_ASSERT( nullptr != fctx_);
  323.         args_tpl_t data{ std::forward< Args >( args) ... };
  324.         auto p = std::make_tuple( fn, std::move( data) );
  325.         detail::transfer_t t = detail::ontop_fcontext(
  326.                 detail::exchange( fctx_, nullptr),
  327.                 & p,
  328.                 detail::context_ontop< execution_context, Fn, Args ... >);
  329.         if ( nullptr != t.data) {
  330.             data = std::move( * static_cast< args_tpl_t * >( t.data) );
  331.         }
  332.         return std::tuple_cat( std::forward_as_tuple( execution_context( t.fctx) ), std::move( data) );
  333.     }
  334.  
  335.     explicit operator bool() const noexcept {
  336.         return nullptr != fctx_;
  337.     }
  338.  
  339.     bool operator!() const noexcept {
  340.         return nullptr == fctx_;
  341.     }
  342.  
  343.     bool operator==( execution_context const& other) const noexcept {
  344.         return fctx_ == other.fctx_;
  345.     }
  346.  
  347.     bool operator!=( execution_context const& other) const noexcept {
  348.         return fctx_ != other.fctx_;
  349.     }
  350.  
  351.     bool operator<( execution_context const& other) const noexcept {
  352.         return fctx_ < other.fctx_;
  353.     }
  354.  
  355.     bool operator>( execution_context const& other) const noexcept {
  356.         return other.fctx_ < fctx_;
  357.     }
  358.  
  359.     bool operator<=( execution_context const& other) const noexcept {
  360.         return ! ( * this > other);
  361.     }
  362.  
  363.     bool operator>=( execution_context const& other) const noexcept {
  364.         return ! ( * this < other);
  365.     }
  366.  
  367.     template< typename charT, class traitsT >
  368.     friend std::basic_ostream< charT, traitsT > &
  369.     operator<<( std::basic_ostream< charT, traitsT > & os, execution_context const& other) {
  370.         if ( nullptr != other.fctx_) {
  371.             return os << other.fctx_;
  372.         } else {
  373.             return os << "{not-a-context}";
  374.         }
  375.     }
  376.  
  377.     void swap( execution_context & other) noexcept {
  378.         std::swap( fctx_, other.fctx_);
  379.     }
  380. };
  381.  
  382. #include <boost/context/execution_context_v2_void.ipp>
  383.  
  384. template< typename ... Args >
  385. void swap( execution_context< Args ... > & l, execution_context< Args ... > & r) noexcept {
  386.     l.swap( r);
  387. }
  388.  
  389. }}
  390.  
  391. #ifdef BOOST_HAS_ABI_HEADERS
  392. # include BOOST_ABI_SUFFIX
  393. #endif
  394.  
  395. #endif // BOOST_CONTEXT_EXECUTION_CONTEXT_H
  396.  
downloadexecution_context_v2.hpp Source code - Download mars Source code
Related Source Codes/Software:
Hero - Elegant transition library for iOS & tvOS 2017-06-09
deep-photo-styletransfer - Code and data for paper "Deep Photo Style Transfer... 2017-06-09
mastodon - A GNU Social-compatible microblogging server ... 2017-06-09
plyr - A simple HTML5, YouTube and Vimeo player ... 2017-06-08
prepack - Prepack is a partial evaluator for JavaScript. Pre... 2017-06-08
Public-APIs - 2017-06-09
lottie-ios - An iOS library to natively render After Effects ve... 2017-06-09
Awesome-Hacking - A collection of various awesome lists for hackers,... 2017-06-09
algorithms - Minimal examples of data structures and algorithms... 2017-06-10
lectures - Oxford Deep NLP 2017 course 2017-06-10
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top