In Figure 5-5 we describe how context switching works for POSIX threads. (Java threads work
exactly the same way, but the Java vocabulary for describing locks is a bit less clear for our
purpose.) Three threads are runnable on two LWPs at time 0. Thread T1 holds a lock. Clearly, T1
and T2 will be the active threads, as they have the highest priorities. We'll imagine that T1 is on
LWP1, T2 on LWP2 , and T3 on the runnable queue.
Figure 5-5. How a Context Switch Works
Approaching time 1, T2 attempted to lock the lock and failed. So, as part of the code for
pthread_mutex_lock(), T2 put itself onto the sleep queue for the lock, then called the
scheduler. The scheduler code ran (still as T2) and decided to run T3. Next, the scheduler stored
away the CPU registers into T2's thread structure and loaded the registers from T3's. (At this
particular instant, it's not defined which thread is running on LWP2, and it's not important, either.)
At time 1, the scheduler code finishes its work and returns with T3 running on LWP2.
At time 2 (see Figure 5-6), T1 releases the mutex. As part of the code for
pthread_mutex_unlock(), it takes the first thread off the lock's sleep queue (T2) and makes
it runnable and releases the mutex. Finally, it calls the scheduler.
Figure 5-6. How a Context Switch Works
The scheduler notices that there's a runnable thread (T2) that has a higher priority than one of the
active threads (T3). The scheduler then sends a signal in order to preempt the thread on LWP2.
Now the scheduler has done its work. It returns, and T1 continues to run. This is the state of the
world at time 2 (with a signal pending).
Search WWH :