Free Trial

Safari Books Online is a digital library providing on-demand subscription access to thousands of learning resources.

Share this Page URL

5.6 Thread Primitives for Sequence Coord... > 5.6.4 Polling, Interrupts, and Seque... - Pg. 282

282 CHAPTER 5 Enforcing Modularity with Virtualization For completeness, the implementation of read of an eventcount is as follows: 1 procedure read (eventcount reference event) 2 acquire (thread_table_lock) 3 e event.count 4 release (thread_table_lock) 5 return e To ensure that read provides before-or-after atomicity, read is implemented as a before-or-after action using locks. The implementation of read of a sequencer is similar. Recall that in Figure 5.8, acquire itself is implemented with a spin loop, polling the lock continuously instead of releasing the processor. Given that acquire and release are used to protect only short sequences of instructions, a spinning imple- mentation is acceptable. Furthermore, inside the thread manager we must use a spinning lock because if acquire ( thread_table_lock ) were to call await to wait until the lock is unlocked, then the thread manager would be calling itself, but it isn't designed to be recursive. In particular, it does not have a base case that could stop recursion. 5.6.4 Polling, Interrupts, and Sequence Coordination Some threads must interact with external devices. For example, the keyboard manager must be able to interact with the keyboard controller on the keyboard, which is a separate, special-purpose processor. As we shall see, this interaction is just another example of sequence coordination. The keyboard controller is a special-purpose processor, which runs a single pro- gram that gathers key strokes. In the terminology of this chapter, we can think of the keyboard controller as a single, hard-wired thread running with its own dedicated processor. When the user presses a key, the keyboard controller thread raises a signal line long enough to set a flip-flop, a digital circuit that can store one bit that the key- board manager can read. The controller thread then lowers the signal line until next time (i.e., until the next keystroke). The flip-flop shared between the controller and the manager allows them to coordinate their activities. In fact, using the shared flip-flop, the keyboard manager can run a wait-for-input loop similar to the one in the receiver: 1 while flip _ flop 5 0 do 2 yield () In this case, the keyboard controller sets the flip-flop and the keyboard manager reads the flip-flip and tests it. If the flip-flop is not set, it reads 0, and the manager yields. If it is set, it falls out of the loop. As a side-effect of reading the flip-flop, it is reset to 0, thus providing a kind of coordination lock. Here we have another example of polling. In polling, a thread keeps check- ing whether another (perhaps hardware) thread needs attention. In our example, the keyboard manager runs every time the scheduler offers it a chance, to see if