90 lines
2.3 KiB
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;
|
|
}
|