Hello Jaeyong,
This function is used to switch the stack and execute a given function.
Why do we have to switch the stack? For instance, what would happen if we do not switch the stack?
in contrast to normal function calls, user-level threads are executed without the need to return from a function. For example, let us assume that a user-level thread executes the following code:
void thread_entry() { int signal_count = 0; for (;;) { wait_for_signal(); signal_count++; printf("signal_count is %d", signal_count); ... } }
Here, the variable 'signal_count' is allocated on the thread's stack because it is a local variable. The function 'wait_for_signal()' blocks the user-level thread for an incoming event and invokes scheduler of other user-level threads. So here, a user-level context switch might happen.
Now, imagine that you have two of such threads running. Let's call them A and B. If they would share one stack, and the threads were scheduled in the order A, then B, the resulting stack would look as follows:
------------------------------------------ <- stack top context of B (i.e., 'signal_count' of B) ------------------------------------------ context of A (i.e., 'signal_count' of A) ------------------------------------------
How would the stack look after the user-level scheduler would now pick A? If we just switched to the last stack pointer used by A, the picture would look like this:
------------------------------------------ context of B (i.e., 'signal_count' of B) ------------------------------------------ <- stack top context of A (i.e., 'signal_count' of A) ------------------------------------------
Now, thread A executes the 'printf' function, which uses the stack and thereby overwrites the context of 'B'. After returning from 'printf', the stack would look like this:
------------------------------------------ left-overs of the printf function ------------------------------------------ <- stack top context of A (i.e., 'signal_count' of A) ------------------------------------------
The context of B has been overwritten by the function call frames used by the 'printf' function and its subroutines.
By hosting the stack of each user-level thread in a distinct memory area, such situations cannot happen. The threads can be executed in any order without overwriting each other's context.
Cheers Norman