diff --git a/emper/ContextManager.cpp b/emper/ContextManager.cpp index 4f813df4a22fd573a38116cb23bcd62ceecaf54b..97c46d131fd31348e0beb89f6cb67df59f71184a 100644 --- a/emper/ContextManager.cpp +++ b/emper/ContextManager.cpp @@ -73,34 +73,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(); }