Switching the CPU from one thread to another involves suspending the current thread, saving its state (e.g., registers), and then restoring the state of the thread being switched to. The thread switch actually completes at the moment a new program counter is loaded into PC; at that point, the CPU is no longer executing the thread switching code, it is executing code associated with the new thread.
The routine Switch(oldThread, nextThread) actually performs a thread switch. Switch saves all of oldThread's state (oldThread is the thread that is executing when Switch is called), so that it can resume executing the thread later, without the thread knowing it was suspended. Switch does the following:
Note: It is crucial that Switch() appear to be a regular procedure call to whoever calls it. That way, threads may call Switch() whenever they want. The call will appear to return just like a normal procedure call except that the return does not take place right away. Only after the scheduler decides to resume execution of the switched thread will it run again.
The routine Switch() is written in assembly language because it is a machine-depended routine. It has to manipulate registers, look into the thread's stack, etc.
Note: After returning from Switch, the previous thread is no longer running. Thread nextThread is running now. But because it also called Switch() previously, it will return to the ``right place'' (the instruction after the call to Switch()). Thus, it looks like Switch() is a ``normal'' procedure call, but in fact, a thread switch has taken place.