diff options
Diffstat (limited to 'boost/context/continuation_ucontext.hpp')
-rw-r--r-- | boost/context/continuation_ucontext.hpp | 81 |
1 files changed, 40 insertions, 41 deletions
diff --git a/boost/context/continuation_ucontext.hpp b/boost/context/continuation_ucontext.hpp index 94457f7e0f..030d3e9ed6 100644 --- a/boost/context/continuation_ucontext.hpp +++ b/boost/context/continuation_ucontext.hpp @@ -82,8 +82,6 @@ static void entry_func( void * data) noexcept { } struct BOOST_CONTEXT_DECL activation_record { - thread_local static activation_record * current_rec; - ucontext_t uctx{}; stack_context sctx{}; bool main_ctx{ true }; @@ -95,7 +93,6 @@ struct BOOST_CONTEXT_DECL activation_record { void * fake_stack{ nullptr }; void * stack_bottom{ nullptr }; std::size_t stack_size{ 0 }; - bool started{ false }; #endif static activation_record *& current() noexcept; @@ -108,10 +105,6 @@ struct BOOST_CONTEXT_DECL activation_record { std::error_code( errno, std::system_category() ), "getcontext() failed"); } -#if defined(BOOST_USE_ASAN) - stack_bottom = uctx.uc_stack.ss_sp; - stack_size = uctx.uc_stack.ss_size; -#endif } activation_record( stack_context sctx_) noexcept : @@ -140,16 +133,19 @@ struct BOOST_CONTEXT_DECL activation_record { __splitstack_setcontext( sctx.segments_ctx); #endif #if defined(BOOST_USE_ASAN) - if ( from->started) { - __sanitizer_finish_switch_fiber( from->fake_stack, (const void **) & from->stack_bottom, - & from->stack_size); - from->started = false; + if ( terminated) { + __sanitizer_start_switch_fiber( nullptr, stack_bottom, stack_size); + } else { + __sanitizer_start_switch_fiber( & from->fake_stack, stack_bottom, stack_size); } - __sanitizer_start_switch_fiber( & fake_stack, stack_bottom, stack_size); - started = true; #endif // context switch from parent context to `this`-context ::swapcontext( & from->uctx, & uctx); +#if defined(BOOST_USE_ASAN) + __sanitizer_finish_switch_fiber( current()->fake_stack, + (const void **) & current()->from->stack_bottom, + & current()->from->stack_size); +#endif #if defined(BOOST_NO_CXX14_STD_EXCHANGE) return exchange( current()->from, nullptr); #else @@ -200,16 +196,15 @@ struct BOOST_CONTEXT_DECL activation_record { __splitstack_setcontext( sctx.segments_ctx); #endif #if defined(BOOST_USE_ASAN) - if ( from->started) { - __sanitizer_finish_switch_fiber( from->fake_stack, (const void **) & from->stack_bottom, - & from->stack_size); - from->started = false; - } - __sanitizer_start_switch_fiber( & fake_stack, stack_bottom, stack_size); - started = true; + __sanitizer_start_switch_fiber( & from->fake_stack, stack_bottom, stack_size); #endif // context switch from parent context to `this`-context ::swapcontext( & from->uctx, & uctx); +#if defined(BOOST_USE_ASAN) + __sanitizer_finish_switch_fiber( current()->fake_stack, + (const void **) & current()->from->stack_bottom, + & current()->from->stack_size); +#endif #if defined(BOOST_NO_CXX14_STD_EXCHANGE) return exchange( current()->from, nullptr); #else @@ -237,11 +232,11 @@ struct forced_unwind { template< typename Ctx, typename StackAlloc, typename Fn > class capture_record : public activation_record { private: - StackAlloc salloc_; + typename std::decay< StackAlloc >::type salloc_; typename std::decay< Fn >::type fn_; static void destroy( capture_record * p) noexcept { - StackAlloc salloc = p->salloc_; + typename std::decay< StackAlloc >::type salloc = std::move( p->salloc_); stack_context sctx = p->sctx; // deallocate activation record p->~capture_record(); @@ -250,9 +245,9 @@ private: } public: - capture_record( stack_context sctx, StackAlloc const& salloc, Fn && fn) noexcept : + capture_record( stack_context sctx, StackAlloc && salloc, Fn && fn) noexcept : activation_record{ sctx }, - salloc_{ salloc }, + salloc_{ std::forward< StackAlloc >( salloc) }, fn_( std::forward< Fn >( fn) ) { } @@ -262,10 +257,15 @@ public: } void run() { +#if defined(BOOST_USE_ASAN) + __sanitizer_finish_switch_fiber( fake_stack, + (const void **) & from->stack_bottom, + & from->stack_size); +#endif Ctx c{ from }; try { // invoke context-function -#if defined(BOOST_NO_CXX17_STD_APPLY) +#if defined(BOOST_NO_CXX17_STD_INVOKE) c = invoke( fn_, std::move( c) ); #else c = std::invoke( fn_, std::move( c) ); @@ -284,7 +284,7 @@ public: }; template< typename Ctx, typename StackAlloc, typename Fn > -static activation_record * create_context1( StackAlloc salloc, Fn && fn) { +static activation_record * create_context1( StackAlloc && salloc, Fn && fn) { typedef capture_record< Ctx, StackAlloc, Fn > capture_t; auto sctx = salloc.allocate(); @@ -294,7 +294,7 @@ static activation_record * create_context1( StackAlloc salloc, Fn && fn) { & ~ static_cast< uintptr_t >( 0xff) ); // placment new for control structure on context stack capture_t * record = new ( storage) capture_t{ - sctx, salloc, std::forward< Fn >( fn) }; + sctx, std::forward< StackAlloc >( salloc), std::forward< Fn >( fn) }; // stack bottom void * stack_bottom = reinterpret_cast< void * >( reinterpret_cast< uintptr_t >( sctx.sp) - static_cast< uintptr_t >( sctx.size) ); @@ -318,7 +318,7 @@ static activation_record * create_context1( StackAlloc salloc, Fn && fn) { } template< typename Ctx, typename StackAlloc, typename Fn > -static activation_record * create_context2( preallocated palloc, StackAlloc salloc, Fn && fn) { +static activation_record * create_context2( preallocated palloc, StackAlloc && salloc, Fn && fn) { typedef capture_record< Ctx, StackAlloc, Fn > capture_t; // reserve space for control structure @@ -327,7 +327,7 @@ static activation_record * create_context2( preallocated palloc, StackAlloc sall & ~ static_cast< uintptr_t >( 0xff) ); // placment new for control structure on context stack capture_t * record = new ( storage) capture_t{ - palloc.sctx, salloc, std::forward< Fn >( fn) }; + palloc.sctx, std::forward< StackAlloc >( salloc), std::forward< Fn >( fn) }; // stack bottom void * stack_bottom = reinterpret_cast< void * >( reinterpret_cast< uintptr_t >( palloc.sctx.sp) - static_cast< uintptr_t >( palloc.sctx.size) ); @@ -360,18 +360,18 @@ private: friend class detail::capture_record; template< typename Ctx, typename StackAlloc, typename Fn > - friend detail::activation_record * detail::create_context1( StackAlloc, Fn &&); + friend detail::activation_record * detail::create_context1( StackAlloc &&, Fn &&); template< typename Ctx, typename StackAlloc, typename Fn > - friend detail::activation_record * detail::create_context2( preallocated, StackAlloc, Fn &&); + friend detail::activation_record * detail::create_context2( preallocated, StackAlloc &&, Fn &&); template< typename StackAlloc, typename Fn > friend continuation - callcc( std::allocator_arg_t, StackAlloc, Fn &&); + callcc( std::allocator_arg_t, StackAlloc &&, Fn &&); template< typename StackAlloc, typename Fn > friend continuation - callcc( std::allocator_arg_t, preallocated, StackAlloc, Fn &&); + callcc( std::allocator_arg_t, preallocated, StackAlloc &&, Fn &&); detail::activation_record * ptr_{ nullptr }; @@ -396,15 +396,14 @@ public: continuation( continuation const&) = delete; continuation & operator=( continuation const&) = delete; - continuation( continuation && other) noexcept : - ptr_{ nullptr } { + continuation( continuation && other) noexcept { swap( other); } continuation & operator=( continuation && other) noexcept { if ( BOOST_LIKELY( this != & other) ) { - ptr_ = other.ptr_; - other.ptr_ = nullptr; + continuation tmp = std::move( other); + swap( tmp); } return * this; } @@ -507,18 +506,18 @@ callcc( Fn && fn) { template< typename StackAlloc, typename Fn > continuation -callcc( std::allocator_arg_t, StackAlloc salloc, Fn && fn) { +callcc( std::allocator_arg_t, StackAlloc && salloc, Fn && fn) { return continuation{ detail::create_context1< continuation >( - salloc, std::forward< Fn >( fn) ) }.resume(); + std::forward< StackAlloc >( salloc), std::forward< Fn >( fn) ) }.resume(); } template< typename StackAlloc, typename Fn > continuation -callcc( std::allocator_arg_t, preallocated palloc, StackAlloc salloc, Fn && fn) { +callcc( std::allocator_arg_t, preallocated palloc, StackAlloc && salloc, Fn && fn) { return continuation{ detail::create_context2< continuation >( - palloc, salloc, std::forward< Fn >( fn) ) }.resume(); + palloc, std::forward< StackAlloc >( salloc), std::forward< Fn >( fn) ) }.resume(); } inline |