p1/machine/Timer.java

90 lines
2.3 KiB
Java

// PART OF THE MACHINE SIMULATION. DO NOT CHANGE.
package nachos.machine;
import nachos.security.*;
/**
* A hardware timer generates a CPU timer interrupt approximately every 500
* clock ticks. This means that it can be used for implementing time-slicing,
* or for having a thread go to sleep for a specific period of time.
*
* The <tt>Timer</tt> class emulates a hardware timer by scheduling a timer
* interrupt to occur every time approximately 500 clock ticks pass. There is
* a small degree of randomness here, so interrupts do not occur exactly every
* 500 ticks.
*/
public final class Timer {
/**
* Allocate a new timer.
*
* @param privilege encapsulates privileged access to the Nachos
* machine.
*/
public Timer(Privilege privilege) {
System.out.print(" timer");
this.privilege = privilege;
timerInterrupt = new Runnable() {
public void run() { timerInterrupt(); }
};
autoGraderInterrupt = new Runnable() {
public void run() {
Machine.autoGrader().timerInterrupt(Timer.this.privilege,
lastTimerInterrupt);
}
};
scheduleInterrupt();
}
/**
* Set the callback to use as a timer interrupt handler. The timer
* interrupt handler will be called approximately every 500 clock ticks.
*
* @param handler the timer interrupt handler.
*/
public void setInterruptHandler(Runnable handler) {
this.handler = handler;
}
/**
* Get the current time.
*
* @return the number of clock ticks since Nachos started.
*/
public long getTime() {
return privilege.stats.totalTicks;
}
private void timerInterrupt() {
scheduleInterrupt();
scheduleAutoGraderInterrupt();
lastTimerInterrupt = getTime();
if (handler != null)
handler.run();
}
private void scheduleInterrupt() {
int delay = Stats.TimerTicks;
delay += Lib.random(delay/10) - (delay/20);
privilege.interrupt.schedule(delay, "timer", timerInterrupt);
}
private void scheduleAutoGraderInterrupt() {
privilege.interrupt.schedule(1, "timerAG", autoGraderInterrupt);
}
private long lastTimerInterrupt;
private Runnable timerInterrupt;
private Runnable autoGraderInterrupt;
private Privilege privilege;
private Runnable handler = null;
}