diff --git a/emper/ContextManager.cpp b/emper/ContextManager.cpp index 3f4cb54d4f8c5fbad3d9e2c4f638cc845da5dc74..92afe0bb17387b72d0fc5cd7fddb76d29116b59e 100644 --- a/emper/ContextManager.cpp +++ b/emper/ContextManager.cpp @@ -72,34 +72,15 @@ void ContextManager::start() { return; } + Context* freeContext = nullptr; if constexpr (emper::CONTINUATION_STEALING) { Fibril::tryResumeFibril(fibrilResumeValue); - // The code below only needs to be executed if we did a long jmp - // before. But optimizing for it is not worth it. If we longjmp - // and can not resume the Fibril and we where not on the initial - // context of the Fibril, then we need to take care to recycle the - // context. - Context* currentContext = Context::getCurrentContext(); - if (currentContext) { - // If we would simply call currentContext->start() here, then we - // would jump to an invalid address. The reason is that as soon as - // the Context::kickoff() is executed, the alpha function address, - // which was just popped of the stack, will be potentially - // overriden by a stack push operation. And such operations are - // very likely. Instead we simply free the current context here, - // so that it is re-initialized later on. - - // TODO: Adjust the assembly to not use 'ret' to reach the - // kickoff function, but instead jmp. This would not destroy the - // kickoff's function pointer on the stack, and we could call - // currentContext->start() here. This would print a small - // performance gain. - putFreeContext(currentContext); - } + freeContext = Context::getCurrentContext(); } - Context* freeContext = getFreeContext(); + if (!freeContext) freeContext = getFreeContext(); + freeContext->start(); }