Next: Real-Time
Clock Interrupts Up: Nachos
Machine Previous: Machine
Components
Interrupt Management
Nachos simulates interrupts by maintaining an event queue together with
a simulated clock. As the clock ticks, the event queue is examined to find
events scheduled to take place now. The clock is maintained entirely in
software and ticks under the following conditions:
-
Every time interrupts are restored (and the restored interrupt mask has
interrupts enabled), the clock advances one tick. Nachos code frequently
disables and restores interrupts for mutual exclusion purposes by making
explicit calls to interrupt::SetLevel().
-
Whenever the MIPS simulator executes one instruction, the clock advances
one tick.
-
Whenever the ready list is empty, the clock advances however many
ticks are needed to fast-forward the current time to that of the next scheduled
event.
Whenever the clock advances, the event queue is examined and any pending
interrupt events are serviced by invoking the procedure associated with
the timer event (e.g., the interrupt service routine). All interrupt service
routines are run with interrupts disabled, and the interrupt service routine
may not re-enable them.
Warning: in interrupt handler may not call any routines that
lead to a context switch of the current thread (e.g., scheduler::Run()
or SWITCH() ). Doing so may lead to deadlock. This restriction is
an artifact of the way interrupts are simulated under Nachos, and should
not be taken as an indication of the way things are done on real machines.
Specifically, consider the case where multiple events happen to be scheduled
at exactly the same time. If the handler for the first event invokes
sleep
(which calls SWITCH), the others won't be serviced at the right
time. In fact, the thread that called sleep may actually be waiting
for one of the other events that is supposed to take place now, but is
delayed because of the SWITCH. We now have a deadlock.
All routines related to interrupt management are provided by the Interrupt
object. The main routines of interest include:
-
void Schedule(VoidFunctionPtr handler, int arg, int when, IntType type)
-
schedules a future event to take place at time when. When it is
time for the scheduled event to take place, Nachos calls the routine handler
with the single argument arg.
-
IntStatus SetLevel(IntStatus level)
-
Change the interrupt mask to level, returning the previous value.
This routine is used to temporarily disable and re-enable interrupts for
mutual exclusion purposes. Only two interrupt levels are supported: IntOn
and IntOff.
-
OneTick()
-
advances the clock one tick and services any pending requests (by calling
CheckIfDue).
It is called from machine::Run() after each user-level instruction
is executed, as well as by SetLevel when the interrupts are restored.
-
bool CheckIfDue(bool advanceClock)
-
examines the event queue for events that need servicing now. If it finds
any, it services them. It is invoked in such places as OneTick.
-
Idle()
-
``advances'' to the clock to the time of the next scheduled event. It is
called by the scheduler (actually Sleep()) when there are no more
threads on the ready list and we want to ``fast-forward'' the time.
|
Nachos
Tutorials
Roadmap
Source Code
Introduction
Threads
Interrupts
Synchronization
System Calls
Exception Handling
Multiprogramming
File System
Networking
Tutorials
Lab 1 Tutorial
Lab 2 Tutorial
Lab 3 Tutorial
Lab 4 Tutorial
Lab 5 Tutorial
|