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();
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; }
#include <ucontext.h>
#endif
+// Avoid fortify source for longjmp to work between ucontext stacks.
+#pragma push_macro("__USE_FORTIFY_LEVEL")
+#undef __USE_FORTIFY_LEVEL
+#include <setjmp.h>
+#pragma pop_macro("__USE_FORTIFY_LEVEL")
+
#include <cstddef>
#include <cstdint>
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.