Annotate the coroutines with TSAN fiber information
This commit is contained in:
parent
e237b6a2af
commit
660d1596e2
|
@ -34,8 +34,15 @@
|
|||
#ifdef KICAD_USE_VALGRIND
|
||||
#include <valgrind/valgrind.h>
|
||||
#endif
|
||||
#ifdef KICAD_SANITIZE_THREADS
|
||||
#include <sanitizer/tsan_interface.h>
|
||||
#endif
|
||||
#ifdef KICAD_SANITIZE_ADDRESS
|
||||
#include <sanitizer/asan_interface.h>
|
||||
#endif
|
||||
|
||||
#include <libcontext.h>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <advanced_config.h>
|
||||
|
||||
|
@ -83,8 +90,32 @@ private:
|
|||
// call context holds a reference to the main stack context
|
||||
};
|
||||
|
||||
using CONTEXT_T = libcontext::fcontext_t;
|
||||
using CALLEE_STORAGE = CONTEXT_T;
|
||||
struct CONTEXT_T
|
||||
{
|
||||
libcontext::fcontext_t ctx; // The context itself
|
||||
#ifdef KICAD_SANITIZE_THREADS
|
||||
void* tsan_fiber; // The TSAN fiber for this context
|
||||
bool own_tsan_fiber; // Do we own this TSAN fiber? (we only delete fibers we own)
|
||||
#endif
|
||||
|
||||
CONTEXT_T() :
|
||||
ctx( nullptr )
|
||||
#ifdef KICAD_SANITIZE_THREADS
|
||||
,tsan_fiber( nullptr )
|
||||
,own_tsan_fiber( true )
|
||||
#endif
|
||||
{}
|
||||
|
||||
~CONTEXT_T()
|
||||
{
|
||||
|
||||
#ifdef KICAD_SANITIZE_THREADS
|
||||
// Only destroy the fiber when we own it
|
||||
if( own_tsan_fiber )
|
||||
__tsan_destroy_fiber( tsan_fiber );
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
class CALL_CONTEXT
|
||||
{
|
||||
|
@ -97,7 +128,7 @@ private:
|
|||
~CALL_CONTEXT()
|
||||
{
|
||||
if( m_mainStackContext )
|
||||
libcontext::release_fcontext( *m_mainStackContext );
|
||||
libcontext::release_fcontext( m_mainStackContext->ctx );
|
||||
}
|
||||
|
||||
|
||||
|
@ -111,7 +142,12 @@ private:
|
|||
m_mainStackFunction = std::move( aFunc );
|
||||
INVOCATION_ARGS args{ INVOCATION_ARGS::CONTINUE_AFTER_ROOT, aCor, this };
|
||||
|
||||
libcontext::jump_fcontext( &aCor->m_callee, *m_mainStackContext,
|
||||
#ifdef KICAD_SANITIZE_THREADS
|
||||
// Tell TSAN we are changing fibers
|
||||
__tsan_switch_to_fiber( m_mainStackContext->tsan_fiber, 0 );
|
||||
#endif
|
||||
|
||||
libcontext::jump_fcontext( &( aCor->m_callee.ctx ), m_mainStackContext->ctx,
|
||||
reinterpret_cast<intptr_t>( &args ) );
|
||||
}
|
||||
|
||||
|
@ -152,12 +188,15 @@ public:
|
|||
m_func( std::move( aEntry ) ),
|
||||
m_running( false ),
|
||||
m_args( 0 ),
|
||||
m_caller( nullptr ),
|
||||
m_caller(),
|
||||
m_callContext( nullptr ),
|
||||
m_callee( nullptr ),
|
||||
m_callee(),
|
||||
m_retVal( 0 )
|
||||
#ifdef KICAD_USE_VALGRIND
|
||||
,valgrind_stack( 0 )
|
||||
#endif
|
||||
#ifdef KICAD_SANITIZE_ADDRESS
|
||||
,asan_stack( nullptr )
|
||||
#endif
|
||||
{
|
||||
m_stacksize = ADVANCED_CFG::GetCfg().m_CoroutineStackSize;
|
||||
|
@ -168,10 +207,10 @@ public:
|
|||
#ifdef KICAD_USE_VALGRIND
|
||||
VALGRIND_STACK_DEREGISTER( valgrind_stack );
|
||||
#endif
|
||||
if(m_caller)
|
||||
libcontext::release_fcontext( m_caller );
|
||||
if(m_callee)
|
||||
libcontext::release_fcontext( m_callee );
|
||||
if( m_caller.ctx )
|
||||
libcontext::release_fcontext( m_caller.ctx );
|
||||
if( m_callee.ctx )
|
||||
libcontext::release_fcontext( m_callee.ctx );
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -222,6 +261,12 @@ public:
|
|||
{
|
||||
CALL_CONTEXT ctx;
|
||||
INVOCATION_ARGS args{ INVOCATION_ARGS::FROM_ROOT, this, &ctx };
|
||||
|
||||
#ifdef KICAD_SANITIZE_THREADS
|
||||
// Get the TSAN fiber for the current stack here
|
||||
m_caller.tsan_fiber = __tsan_get_current_fiber();
|
||||
m_caller.own_tsan_fiber = false;
|
||||
#endif
|
||||
ctx.Continue( doCall( &args, aArg ) );
|
||||
|
||||
return Running();
|
||||
|
@ -256,6 +301,12 @@ public:
|
|||
{
|
||||
CALL_CONTEXT ctx;
|
||||
INVOCATION_ARGS args{ INVOCATION_ARGS::FROM_ROOT, this, &ctx };
|
||||
|
||||
#ifdef KICAD_SANITIZE_THREADS
|
||||
// Get the TSAN fiber for the current stack here
|
||||
m_caller.tsan_fiber = __tsan_get_current_fiber();
|
||||
m_caller.own_tsan_fiber = false;
|
||||
#endif
|
||||
ctx.Continue( doResume( &args ) );
|
||||
|
||||
return Running();
|
||||
|
@ -298,7 +349,7 @@ private:
|
|||
INVOCATION_ARGS* doCall( INVOCATION_ARGS* aInvArgs, ArgType aArgs )
|
||||
{
|
||||
assert( m_func );
|
||||
assert( !m_callee );
|
||||
assert( !( m_callee.ctx ) );
|
||||
|
||||
m_args = &aArgs;
|
||||
|
||||
|
@ -323,7 +374,12 @@ private:
|
|||
#endif
|
||||
#endif
|
||||
|
||||
m_callee = libcontext::make_fcontext( sp, stackSize, callerStub );
|
||||
#ifdef KICAD_SANITIZE_THREADS
|
||||
// Create a new fiber to go with the new context
|
||||
m_callee.tsan_fiber = __tsan_create_fiber( 0 );
|
||||
m_callee.own_tsan_fiber = true;
|
||||
#endif
|
||||
m_callee.ctx = libcontext::make_fcontext( sp, stackSize, callerStub );
|
||||
m_running = true;
|
||||
|
||||
// off we go!
|
||||
|
@ -357,8 +413,12 @@ private:
|
|||
|
||||
INVOCATION_ARGS* jumpIn( INVOCATION_ARGS* args )
|
||||
{
|
||||
#ifdef KICAD_SANITIZE_THREADS
|
||||
// Tell TSAN we are changing fibers to the callee
|
||||
__tsan_switch_to_fiber( m_callee.tsan_fiber, 0 );
|
||||
#endif
|
||||
args = reinterpret_cast<INVOCATION_ARGS*>(
|
||||
libcontext::jump_fcontext( &m_caller, m_callee,
|
||||
libcontext::jump_fcontext( &( m_caller.ctx ), m_callee.ctx,
|
||||
reinterpret_cast<intptr_t>( args ) )
|
||||
);
|
||||
|
||||
|
@ -370,8 +430,12 @@ private:
|
|||
INVOCATION_ARGS args{ INVOCATION_ARGS::FROM_ROUTINE, nullptr, nullptr };
|
||||
INVOCATION_ARGS* ret;
|
||||
|
||||
#ifdef KICAD_SANITIZE_THREADS
|
||||
// Tell TSAN we are changing fibers back to the caller
|
||||
__tsan_switch_to_fiber( m_caller.tsan_fiber, 0 );
|
||||
#endif
|
||||
ret = reinterpret_cast<INVOCATION_ARGS*>(
|
||||
libcontext::jump_fcontext( &m_callee, m_caller,
|
||||
libcontext::jump_fcontext( &( m_callee.ctx ), m_caller.ctx,
|
||||
reinterpret_cast<intptr_t>( &args ) )
|
||||
);
|
||||
|
||||
|
@ -403,13 +467,16 @@ private:
|
|||
CALL_CONTEXT* m_callContext;
|
||||
|
||||
///< saved coroutine context
|
||||
CALLEE_STORAGE m_callee;
|
||||
CONTEXT_T m_callee;
|
||||
|
||||
ReturnType m_retVal;
|
||||
|
||||
#ifdef KICAD_USE_VALGRIND
|
||||
uint32_t valgrind_stack;
|
||||
#endif
|
||||
#ifdef KICAD_SANITIZE_ADDRESS
|
||||
void* asan_stack;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue