diff --git a/src/base/fiber.cc b/src/base/fiber.cc index 3d2e2e947a..fe1bad09a8 100644 --- a/src/base/fiber.cc +++ b/src/base/fiber.cc @@ -145,10 +145,12 @@ Fiber::start() setStarted(); - // Swap back to the parent context which is still considered "current", - // now that we're ready to go. - int ret M5_VAR_USED = swapcontext(&ctx, &_currentFiber->ctx); - panic_if(ret == -1, strerror(errno)); + if (_setjmp(jmp) == 0) { + // Swap back to the parent context which is still considered "current", + // now that we're ready to go. + int ret = swapcontext(&ctx, &_currentFiber->ctx); + panic_if(ret == -1, strerror(errno)); + } // Call main() when we're been reactivated for the first time. main(); @@ -175,7 +177,8 @@ Fiber::run() Fiber *prev = _currentFiber; Fiber *next = this; _currentFiber = next; - swapcontext(&prev->ctx, &next->ctx); + if (_setjmp(prev->jmp) == 0) + _longjmp(next->jmp, 1); } Fiber *Fiber::currentFiber() { return _currentFiber; } diff --git a/src/base/fiber.hh b/src/base/fiber.hh index dc7ef019fd..be8937f18f 100644 --- a/src/base/fiber.hh +++ b/src/base/fiber.hh @@ -39,6 +39,12 @@ #include #endif +// Avoid fortify source for longjmp to work between ucontext stacks. +#pragma push_macro("__USE_FORTIFY_LEVEL") +#undef __USE_FORTIFY_LEVEL +#include +#pragma pop_macro("__USE_FORTIFY_LEVEL") + #include #include @@ -137,6 +143,10 @@ class Fiber void start(); ucontext_t ctx; + // ucontext is slow in swapcontext. Here we use _setjmp/_longjmp to avoid + // the additional signals for speed up. + jmp_buf jmp; + Fiber *link; // The stack for this context, or a nullptr if allocated elsewhere.