
114 Chapter 8: Operating Systems
The contextSwitch routine is actually invoked by the scheduler, which is in turn
called from one of the operating system calls that disables interrupts. So it is not
necessary to disable interrupts here. In addition, because the operating system call
that invoked the scheduler is written in a high-level language, most of the running
task’s registers have already been saved onto its local stack. That reduces the
amount of work that needs to be done by the routines saveContext and
restoreContext. They need only worry about saving the instruction pointer, stack
pointer, and flags.
The actual behavior of contextSwitch at runtime is difficult to see simply by look-
ing at the previous code. Most software developers think serially, assuming that
each line of code will be executed immediately following the previous one. How-
ever, this code is actually executed two times, in pseudoparallel. When one task
(the new task) changes to the running state, another (the old task) must simulta-
neously go back to the ready state. Imagine what the new task sees when it is
restored inside the restoreContext code. No matter what the new task was doing
before, it always wakes up inside the saveContext code—because that’s where its
instruction pointer was saved.
How does the new task know whether it is coming out of saveContext for the first
time (i.e., in the process of going to sleep) ...