summaryrefslogtreecommitdiff
path: root/boost/context/continuation_ucontext.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/context/continuation_ucontext.hpp')
-rw-r--r--boost/context/continuation_ucontext.hpp81
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