Juicebox
Juicebox

Reputation: 442

make_fcontext/jump_fcontext used with shared stack

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

Answers (1)

xlrg
xlrg

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

Related Questions