Reputation: 442
Is there a way to use boost context make_fcontext/jump_fcontext with a shared stack to share coroutine memory by saving/restoring the stack ?
It seems that make_fcontext and jump_fcontext write on the stack themselves and I get crashes when trying to save/restore stack on yield/resume, but it is really hard for me to get what happens as make_fcontext/jump_fcontext are pure assembly code.
Here is the coroutine methods which trigger segmentation fault (the same code works very well if I use a different stack for each coroutine and I don't use the saveStack/restoreStack)
void resume()
{
if (yielded)
{
restoreStack();
yielded = false;
}
else
{
running = true;
thisContext = boost::context::make_fcontext(
(char*)sharedStackPtr + sharedStackSize ,
sharedStackSize,
my_entry_func);
}
boost::context::jump_fcontext(&yieldContext, thisContext, reinterpret_cast<intptr_t>(this));
}
void yield()
{
yielded = true;
saveStack();
boost::context::jump_fcontext(&thisContext, yieldContext, 0);
}
void restoreStack()
{
char* stackTop = (char*)sharedStackPtr + sharedStackSize ;
memcpy(stackTop - savedStackSize, savedStackPtr, savedStackSize);
}
void saveStack()
{
char dummy = 0;
char* stackPointer = &dummy;
char* stackTop = (char*)sharedStackPtr + sharedStackSize ;
assert((stackPointer < stackTop) && (stackPointer >= sharedStackPtr ));
savedStackSize = stackTop - stackPointer;
if (savedStackPtr == nullptr)
{
savedStackPtr = coroutine_stack_alloc(savedStackSize);
}
else
{
savedStackPtr = coroutine_stack_realloc(savedStackPtr, savedStackSize);
}
memcpy(savedStackPtr, stackPointer, savedStackSize);
}
Any idea ? Is there something I do wrong somewhere ?
Upvotes: 0
Views: 1531
Reputation: 2109
make_fcontext() must be applied to a stack inorder to initialize the stack before it can be used with jump_fcontext(). Ofcourse you could re-use a stack by applying make_fcontext() after the execution context is finished.
Upvotes: 1