cmultithreadingstackfiber

Why does the implementation of user level thread (fiber) require a new allocated stack per fiber?


In C fibers can be coded using setjmp() and longjmp() to implement context switches at user level.
As described in evanjones.ca and Portable Multithreading(pdf) it is also required that each fiber has a newly allocated stack.
Since a fiber lives in a thread context, when it is invoked will have automatically a stack frame associated to it, so why is it required this new allocated stack? : when a fiber wants to switch to another one, the following approach could be used :

 cpu_context[N] :global array where the i-th entry is the cpu context(jmp_buffer) of the i-th fiber 

fiber_ith :
   [...]
   if ( setjmp(cpu_context[i]) == 0 ){
        longjmp(cpu_context[j])
   }
   [...]

The necessity of a new stack is due to the fact that as written here, it is not possible to use longjmp()to go back to a fiber execution whose stack frame is not anymore valid from the instant that fiber calls longjmp() ?

EDIT : these fibers must be non preemtive and can voluntary switch from one fiber to another one


Solution

  • Suppose a fiber has a function that calls another function that calls another function that then causes that fiber to be switched for another fiber. When we resume this fiber, we need to ensure that all local variables are back the way they were when the fiber switched and we need to ensure that returning from this function goes back to the calling function. Thus the following rules emerge:

    1. While a fiber is running, it can change its stack.
    2. When a fiber is resumed, the stack must be back where it was when the fiber was switched.

    It immediately follows from these two rules that every fiber must have its own stack.