34#ifdef KICAD_USE_VALGRIND
35#include <valgrind/valgrind.h>
37#ifdef KICAD_SANITIZE_THREADS
38#include <sanitizer/tsan_interface.h>
40#ifdef KICAD_SANITIZE_ADDRESS
41#include <sanitizer/asan_interface.h>
44#include <libcontext.h>
74template <
typename ReturnType,
typename ArgType>
98 libcontext::fcontext_t
ctx;
99#ifdef KICAD_SANITIZE_THREADS
106#ifdef KICAD_SANITIZE_THREADS
107 ,tsan_fiber( nullptr )
108 ,own_tsan_fiber( true )
114#ifdef KICAD_SANITIZE_THREADS
117 __tsan_destroy_fiber( tsan_fiber );
147#ifdef KICAD_SANITIZE_THREADS
153 reinterpret_cast<intptr_t
>( &args ) );
181 COROUTINE( T*
object, ReturnType(T::*ptr)( ArgType ) ) :
189 COROUTINE( std::function<ReturnType(ArgType)> aEntry ) :
197#ifdef KICAD_USE_VALGRIND
198 ,m_valgrind_stack( 0 )
200#ifdef KICAD_SANITIZE_ADDRESS
201 ,asan_stack( nullptr )
209#ifdef KICAD_USE_VALGRIND
210 VALGRIND_STACK_DEREGISTER( m_valgrind_stack );
269#ifdef KICAD_SANITIZE_THREADS
271 m_caller.tsan_fiber = __tsan_get_current_fiber();
315#ifdef KICAD_SANITIZE_THREADS
317 m_caller.tsan_fiber = __tsan_get_current_fiber();
377#ifndef LIBCONTEXT_HAS_OWN_STACK
380 m_stack.reset(
new char[stackSize] );
383 sp = (
void*)((((ptrdiff_t)
m_stack.get()) + stackSize - 0xf) & (~0x0f));
386 stackSize -= size_t( ( (ptrdiff_t)
m_stack.get() + stackSize ) - (ptrdiff_t) sp );
388#ifdef KICAD_USE_VALGRIND
389 m_valgrind_stack = VALGRIND_STACK_REGISTER( sp,
m_stack.get() );
393#ifdef KICAD_SANITIZE_THREADS
395 m_callee.tsan_fiber = __tsan_create_fiber( 0 );
398 __tsan_set_fiber_name(
m_callee.tsan_fiber,
"Coroutine fiber" );
407 return jumpIn( aInvArgs );
437#ifdef KICAD_SANITIZE_THREADS
439 __tsan_switch_to_fiber(
m_callee.tsan_fiber, 0 );
446 reinterpret_cast<intptr_t
>( args ) )
457#ifdef KICAD_SANITIZE_THREADS
459 __tsan_switch_to_fiber(
m_caller.tsan_fiber, 0 );
466 reinterpret_cast<intptr_t
>( &args ) )
482 std::function<ReturnType( ArgType )>
m_func;
488 typename std::remove_reference<ArgType>::type*
m_args;
501#ifdef KICAD_USE_VALGRIND
502 uint32_t m_valgrind_stack;
504#ifdef KICAD_SANITIZE_ADDRESS
int m_CoroutineStackSize
Set the stack size for coroutines.
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
CONTEXT_T * m_mainStackContext
void SetMainStack(CONTEXT_T *aStack)
void RunMainStack(COROUTINE *aCor, std::function< void()> aFunc)
void Continue(INVOCATION_ARGS *args)
std::function< void()> m_mainStackFunction
std::unique_ptr< char[]> m_stack
bool Call(ArgType aArg)
Start execution of a coroutine, passing args as its arguments.
CALL_CONTEXT * m_callContext
saved coroutine context
void KiYield(ReturnType &aRetVal)
KiYield with a value.
void KiYield()
Stop execution of the coroutine and returns control to the caller.
CONTEXT_T m_caller
main stack information
bool Resume()
Resume execution of a previously yielded coroutine.
COROUTINE(std::function< ReturnType(ArgType)> aEntry)
Create a coroutine from a delegate object.
static void callerStub(intptr_t aData)
INVOCATION_ARGS * jumpIn(INVOCATION_ARGS *args)
const ReturnType & ReturnValue() const
Return the yielded value (the argument KiYield() was called with).
INVOCATION_ARGS * doResume(INVOCATION_ARGS *args)
bool m_running
pointer to coroutine entry arguments.
INVOCATION_ARGS * doCall(INVOCATION_ARGS *aInvArgs, ArgType aArgs)
bool Call(const COROUTINE &aCor, ArgType aArg)
Start execution of a coroutine, passing args as its arguments.
std::function< ReturnType(ArgType)> m_func
bool Resume(const COROUTINE &aCor)
Resume execution of a previously yielded coroutine.
COROUTINE(T *object, ReturnType(T::*ptr)(ArgType))
Create a coroutine from a member method of an object.
void RunMainStack(std::function< void()> func)
Run a functor inside the application main stack context.
void jumpOut()
coroutine stack
std::remove_reference< ArgType >::type * m_args
saved caller context
const wxChar *const kicadTraceCoroutineStack
Flag to enable tracing of the coroutine call stack.
libcontext::fcontext_t ctx
enum COROUTINE::INVOCATION_ARGS::@36 type
wxLogTrace helper definitions.