Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • flow/emper
  • aj46ezos/emper
  • i4/manycore/emper
3 results
Show changes
Commits on Source (4)
......@@ -106,6 +106,14 @@ class EMPER_CONTEXT_ALIGNAS Context : Logger<LogSubsystem::C> {
static auto calcBos(char* context) -> void*;
auto calcBos() -> void*;
/*
* Used by ContextManager to re-initialize a cached unused context.
*/
inline void reinit() {
currentFiber = nullptr;
savedStackpointer = const_cast<void*>(alphaFunctionIpLocation);
}
public:
Context(func_t mainFunction);
......
......@@ -31,6 +31,7 @@ auto ContextManager::getFreeContext() -> Context* {
}
auto* context = static_cast<Context*>(memory);
context->reinit();
if constexpr (emper::STATS_STACK_USAGE == emper::StatsStackUsage::accurate) {
// If we want accurate stack-usage stats, then we need to re-mark
// the stack if we got the memory from the memory manager but if
......@@ -45,7 +46,7 @@ void ContextManager::putFreeContext(Context* context) {
context->recordStackUsage();
}
if constexpr (!emper::CONTEXT_MANAGER_WITH_MEMORY_MANAGER) {
if constexpr (emper::CONTEXT_MANAGER_WITH_MEMORY_MANAGER) {
putMemory(context);
} else {
delete context;
......@@ -72,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();
}
......@@ -147,6 +129,7 @@ void ContextManager::discardAndResume(Context* context) {
// the end of its dispatch loop, and hence we need to ensure that
// its fiber is recycled.
AbstractFiber* currentFiber = contextToFree->getFiber();
assert(currentFiber);
runtime.dispatcher.recycle(currentFiber);
contextToFree->discardAndResume(context);
......