diff --git a/include/boost/context/fiber_ucontext.hpp b/include/boost/context/fiber_ucontext.hpp index c68cba6..859b7bc 100644 --- a/include/boost/context/fiber_ucontext.hpp +++ b/include/boost/context/fiber_ucontext.hpp @@ -53,6 +53,10 @@ extern "C" { # include BOOST_ABI_PREFIX #endif +#ifdef BOOST_USE_TSAN +#include +#endif + namespace boost { namespace context { namespace detail { @@ -82,6 +86,11 @@ struct BOOST_CONTEXT_DECL fiber_activation_record { std::size_t stack_size{ 0 }; #endif +#if defined(BOOST_USE_TSAN) + void * tsan_fiber{ nullptr }; + bool destroy_tsan_fiber{ true }; +#endif + static fiber_activation_record *& current() noexcept; // used for toplevel-context @@ -92,6 +101,11 @@ struct BOOST_CONTEXT_DECL fiber_activation_record { std::error_code( errno, std::system_category() ), "getcontext() failed"); } + +#if defined(BOOST_USE_TSAN) + tsan_fiber = __tsan_get_current_fiber(); + destroy_tsan_fiber = false; +#endif } fiber_activation_record( stack_context sctx_) noexcept : @@ -100,6 +114,10 @@ struct BOOST_CONTEXT_DECL fiber_activation_record { } virtual ~fiber_activation_record() { +#if defined(BOOST_USE_TSAN) + if (destroy_tsan_fiber) + __tsan_destroy_fiber(tsan_fiber); +#endif } fiber_activation_record( fiber_activation_record const&) = delete; @@ -125,6 +143,9 @@ struct BOOST_CONTEXT_DECL fiber_activation_record { } else { __sanitizer_start_switch_fiber( & from->fake_stack, stack_bottom, stack_size); } +#endif +#if defined (BOOST_USE_TSAN) + __tsan_switch_to_fiber(tsan_fiber, 0); #endif // context switch from parent context to `this`-context ::swapcontext( & from->uctx, & uctx); @@ -184,6 +205,9 @@ struct BOOST_CONTEXT_DECL fiber_activation_record { #endif #if defined(BOOST_USE_ASAN) __sanitizer_start_switch_fiber( & from->fake_stack, stack_bottom, stack_size); +#endif +#if defined (BOOST_USE_TSAN) + __tsan_switch_to_fiber(tsan_fiber, 0); #endif // context switch from parent context to `this`-context ::swapcontext( & from->uctx, & uctx); @@ -314,6 +338,9 @@ static fiber_activation_record * create_fiber1( StackAlloc && salloc, Fn && fn) #if defined(BOOST_USE_ASAN) record->stack_bottom = record->uctx.uc_stack.ss_sp; record->stack_size = record->uctx.uc_stack.ss_size; +#endif +#if defined (BOOST_USE_TSAN) + record->tsan_fiber = __tsan_create_fiber(0); #endif return record; } @@ -349,6 +376,9 @@ static fiber_activation_record * create_fiber2( preallocated palloc, StackAlloc #if defined(BOOST_USE_ASAN) record->stack_bottom = record->uctx.uc_stack.ss_sp; record->stack_size = record->uctx.uc_stack.ss_size; +#endif +#if defined (BOOST_USE_TSAN) + record->tsan_fiber = __tsan_create_fiber(0); #endif return record; }