0

共有スタックでブースト コンテキスト make_fcontext/jump_fcontext を使用して、スタックを保存/復元することでコルーチン メモリを共有する方法はありますか?

make_fcontextとjump_fcontextはスタック自体に書き込み、 yield /resume でスタックを保存/復元しようとするとクラッシュするようですが、make_fcontext/jump_fcontext は純粋なアセンブリ コードであるため、何が起こるかを理解するのは非常に困難です。

これは、セグメンテーション違反をトリガーするコルーチン メソッドです (コルーチンごとに異なるスタックを使用し、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);
    }

何か案が ?どこか間違っていることがありますか?

4

1 に答える 1

1

jump_fcontext() で使用する前にスタックを初期化するために、make_fcontext() をスタックに適用する必要があります。もちろん、実行コンテキストが終了した後に make_fcontext() を適用することで、スタックを再利用できます。

于 2016-11-17T10:18:14.013 に答える