Annotate the coroutines with TSAN fiber information
This commit is contained in:
parent
e237b6a2af
commit
660d1596e2
|
@ -34,8 +34,15 @@
|
||||||
#ifdef KICAD_USE_VALGRIND
|
#ifdef KICAD_USE_VALGRIND
|
||||||
#include <valgrind/valgrind.h>
|
#include <valgrind/valgrind.h>
|
||||||
#endif
|
#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 <libcontext.h>
|
||||||
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <advanced_config.h>
|
#include <advanced_config.h>
|
||||||
|
|
||||||
|
@ -83,8 +90,32 @@ private:
|
||||||
// call context holds a reference to the main stack context
|
// call context holds a reference to the main stack context
|
||||||
};
|
};
|
||||||
|
|
||||||
using CONTEXT_T = libcontext::fcontext_t;
|
struct CONTEXT_T
|
||||||
using CALLEE_STORAGE = 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
|
class CALL_CONTEXT
|
||||||
{
|
{
|
||||||
|
@ -96,8 +127,8 @@ private:
|
||||||
|
|
||||||
~CALL_CONTEXT()
|
~CALL_CONTEXT()
|
||||||
{
|
{
|
||||||
if ( m_mainStackContext )
|
if( m_mainStackContext )
|
||||||
libcontext::release_fcontext( *m_mainStackContext );
|
libcontext::release_fcontext( m_mainStackContext->ctx );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -111,7 +142,12 @@ private:
|
||||||
m_mainStackFunction = std::move( aFunc );
|
m_mainStackFunction = std::move( aFunc );
|
||||||
INVOCATION_ARGS args{ INVOCATION_ARGS::CONTINUE_AFTER_ROOT, aCor, this };
|
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 ) );
|
reinterpret_cast<intptr_t>( &args ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,12 +188,15 @@ public:
|
||||||
m_func( std::move( aEntry ) ),
|
m_func( std::move( aEntry ) ),
|
||||||
m_running( false ),
|
m_running( false ),
|
||||||
m_args( 0 ),
|
m_args( 0 ),
|
||||||
m_caller( nullptr ),
|
m_caller(),
|
||||||
m_callContext( nullptr ),
|
m_callContext( nullptr ),
|
||||||
m_callee( nullptr ),
|
m_callee(),
|
||||||
m_retVal( 0 )
|
m_retVal( 0 )
|
||||||
#ifdef KICAD_USE_VALGRIND
|
#ifdef KICAD_USE_VALGRIND
|
||||||
,valgrind_stack( 0 )
|
,valgrind_stack( 0 )
|
||||||
|
#endif
|
||||||
|
#ifdef KICAD_SANITIZE_ADDRESS
|
||||||
|
,asan_stack( nullptr )
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
m_stacksize = ADVANCED_CFG::GetCfg().m_CoroutineStackSize;
|
m_stacksize = ADVANCED_CFG::GetCfg().m_CoroutineStackSize;
|
||||||
|
@ -168,10 +207,10 @@ public:
|
||||||
#ifdef KICAD_USE_VALGRIND
|
#ifdef KICAD_USE_VALGRIND
|
||||||
VALGRIND_STACK_DEREGISTER( valgrind_stack );
|
VALGRIND_STACK_DEREGISTER( valgrind_stack );
|
||||||
#endif
|
#endif
|
||||||
if(m_caller)
|
if( m_caller.ctx )
|
||||||
libcontext::release_fcontext( m_caller );
|
libcontext::release_fcontext( m_caller.ctx );
|
||||||
if(m_callee)
|
if( m_callee.ctx )
|
||||||
libcontext::release_fcontext( m_callee );
|
libcontext::release_fcontext( m_callee.ctx );
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -222,6 +261,12 @@ public:
|
||||||
{
|
{
|
||||||
CALL_CONTEXT ctx;
|
CALL_CONTEXT ctx;
|
||||||
INVOCATION_ARGS args{ INVOCATION_ARGS::FROM_ROOT, this, &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 ) );
|
ctx.Continue( doCall( &args, aArg ) );
|
||||||
|
|
||||||
return Running();
|
return Running();
|
||||||
|
@ -256,6 +301,12 @@ public:
|
||||||
{
|
{
|
||||||
CALL_CONTEXT ctx;
|
CALL_CONTEXT ctx;
|
||||||
INVOCATION_ARGS args{ INVOCATION_ARGS::FROM_ROOT, this, &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 ) );
|
ctx.Continue( doResume( &args ) );
|
||||||
|
|
||||||
return Running();
|
return Running();
|
||||||
|
@ -298,7 +349,7 @@ private:
|
||||||
INVOCATION_ARGS* doCall( INVOCATION_ARGS* aInvArgs, ArgType aArgs )
|
INVOCATION_ARGS* doCall( INVOCATION_ARGS* aInvArgs, ArgType aArgs )
|
||||||
{
|
{
|
||||||
assert( m_func );
|
assert( m_func );
|
||||||
assert( !m_callee );
|
assert( !( m_callee.ctx ) );
|
||||||
|
|
||||||
m_args = &aArgs;
|
m_args = &aArgs;
|
||||||
|
|
||||||
|
@ -323,7 +374,12 @@ private:
|
||||||
#endif
|
#endif
|
||||||
#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;
|
m_running = true;
|
||||||
|
|
||||||
// off we go!
|
// off we go!
|
||||||
|
@ -357,8 +413,12 @@ private:
|
||||||
|
|
||||||
INVOCATION_ARGS* jumpIn( INVOCATION_ARGS* args )
|
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*>(
|
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 ) )
|
reinterpret_cast<intptr_t>( args ) )
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -370,8 +430,12 @@ private:
|
||||||
INVOCATION_ARGS args{ INVOCATION_ARGS::FROM_ROUTINE, nullptr, nullptr };
|
INVOCATION_ARGS args{ INVOCATION_ARGS::FROM_ROUTINE, nullptr, nullptr };
|
||||||
INVOCATION_ARGS* ret;
|
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*>(
|
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 ) )
|
reinterpret_cast<intptr_t>( &args ) )
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -403,13 +467,16 @@ private:
|
||||||
CALL_CONTEXT* m_callContext;
|
CALL_CONTEXT* m_callContext;
|
||||||
|
|
||||||
///< saved coroutine context
|
///< saved coroutine context
|
||||||
CALLEE_STORAGE m_callee;
|
CONTEXT_T m_callee;
|
||||||
|
|
||||||
ReturnType m_retVal;
|
ReturnType m_retVal;
|
||||||
|
|
||||||
#ifdef KICAD_USE_VALGRIND
|
#ifdef KICAD_USE_VALGRIND
|
||||||
uint32_t valgrind_stack;
|
uint32_t valgrind_stack;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef KICAD_SANITIZE_ADDRESS
|
||||||
|
void* asan_stack;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue