32 #include <type_traits> 34 #ifdef KICAD_USE_VALGRIND 35 #include <valgrind/valgrind.h> 38 #include <libcontext.h> 64 template <
typename ReturnType,
typename ArgType>
115 reinterpret_cast<intptr_t>( &args ) );
143 COROUTINE( T*
object, ReturnType(T::*ptr)( ArgType ) ) :
151 COROUTINE( std::function<ReturnType(ArgType)> aEntry ) :
159 #ifdef KICAD_USE_VALGRIND
168 #ifdef KICAD_USE_VALGRIND 169 VALGRIND_STACK_DEREGISTER( valgrind_stack );
172 libcontext::release_fcontext(
m_caller );
174 libcontext::release_fcontext(
m_callee );
225 ctx.Continue(
doCall( &args, aArg ) );
298 INVOCATION_ARGS*
doCall( INVOCATION_ARGS* aInvArgs, ArgType aArgs )
310 #ifndef LIBCONTEXT_HAS_OWN_STACK 313 m_stack.reset(
new char[stackSize] );
316 sp = (
void*)((((ptrdiff_t)
m_stack.get()) + stackSize - 0xf) & (~0x0f));
319 stackSize -= size_t( ( (ptrdiff_t)
m_stack.get() + stackSize ) - (ptrdiff_t) sp );
321 #ifdef KICAD_USE_VALGRIND 322 valgrind_stack = VALGRIND_STACK_REGISTER( sp,
m_stack.get() );
330 return jumpIn( aInvArgs );
341 INVOCATION_ARGS& args = *reinterpret_cast<INVOCATION_ARGS*>( aData );
358 INVOCATION_ARGS*
jumpIn( INVOCATION_ARGS* args )
360 args = reinterpret_cast<INVOCATION_ARGS*>(
362 reinterpret_cast<intptr_t>( args ) )
371 INVOCATION_ARGS* ret;
373 ret = reinterpret_cast<INVOCATION_ARGS*>(
375 reinterpret_cast<intptr_t>( &args ) )
391 std::function<ReturnType( ArgType )>
m_func;
397 typename std::remove_reference<ArgType>::type*
m_args;
410 #ifdef KICAD_USE_VALGRIND 411 uint32_t valgrind_stack;
void RunMainStack(std::function< void()> func)
Run a functor inside the application main stack context.
std::function< ReturnType(ArgType)> m_func
void KiYield(ReturnType &aRetVal)
KiYield with a value.
bool m_running
pointer to coroutine entry arguments.
void RunMainStack(COROUTINE *aCor, std::function< void()> aFunc)
void jumpOut()
coroutine stack
bool Call(ArgType aArg)
Start execution of a coroutine, passing args as its arguments.
bool Resume(const COROUTINE &aCor)
Resume execution of a previously yielded coroutine.
CALL_CONTEXT * m_callContext
saved coroutine context
CONTEXT_T * m_mainStackContext
std::unique_ptr< char[]> m_stack
bool Call(const COROUTINE &aCor, ArgType aArg)
Start execution of a coroutine, passing args as its arguments.
std::function< void()> m_mainStackFunction
CONTEXT_T m_caller
main stack information
INVOCATION_ARGS * doCall(INVOCATION_ARGS *aInvArgs, ArgType aArgs)
bool Resume()
Resume execution of a previously yielded coroutine.
std::remove_reference< ArgType >::type * m_args
saved caller context
void SetMainStack(CONTEXT_T *aStack)
const ReturnType & ReturnValue() const
Return the yielded value (the argument KiYield() was called with).
INVOCATION_ARGS * doResume(INVOCATION_ARGS *args)
int m_CoroutineStackSize
Set the stack size for coroutines.
void Continue(INVOCATION_ARGS *args)
static void callerStub(intptr_t aData)
INVOCATION_ARGS * jumpIn(INVOCATION_ARGS *args)
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
libcontext::fcontext_t CONTEXT_T
enum COROUTINE::INVOCATION_ARGS::@32 type
COROUTINE(std::function< ReturnType(ArgType)> aEntry)
Create a coroutine from a delegate object.
void KiYield()
Stop execution of the coroutine and returns control to the caller.
COROUTINE(T *object, ReturnType(T::*ptr)(ArgType))
Create a coroutine from a member method of an object.