Untitled
unknown
java
3 years ago
4.3 kB
23
Indexable
package nachos.threads;
import nachos.machine.*;
// import priority queue
import java.util.PriorityQueue;
/**
* Uses the hardware timer to provide preemption, and to allow threads to sleep
* until a certain time.
*/
public class Alarm {
/**
* Allocate a new Alarm. Set the machine's timer interrupt handler to this
* alarm's callback.
* <p>
* <b>Note</b>: Nachos will not function correctly with more than one
* alarm.
*/
public Alarm() {
Machine.timer().setInterruptHandler(new Runnable() {
public void run() {
timerInterrupt();
}
});
}
/**
* The timer interrupt handler. This is called by the machine's timer
* periodically (approximately every 500 clock ticks). Causes the current
* thread to yield, forcing a context switch if there is another thread
* that should be run.
*/
public void timerInterrupt() {
// KThread.currentThread().yield1();
// disable interrupt
boolean intStatus = Machine.interrupt().disable();
while (!waitQueue.isEmpty() && waitQueue.peek().wakeTime <= Machine.timer().getTime()) {
// Retrieves and removes the head of the queue, or return null if this queue is empty.
// then set the current thread from waiting state in waitQueue to ready state in ready queue.
// waitQueue.poll().thread.ready();
WaitingThread test = waitQueue.poll();
test.wakeWaitingThread();
}
// Preempt current thread as normal
// KThread.yield1();
// enable interrupt
Machine.interrupt().restore(intStatus);
}
/**
* Put the current thread to sleep for at least <i>x</i> ticks,
* waking it up in the timer interrupt handler. The thread must be
* woken up (placed in the scheduler ready set) during the first timer
* interrupt where
*
* <p>
* <blockquote>
* (current time) >= (WaitUntil called time)+(x)
* </blockquote>
*
* @param x the minimum number of clock ticks to wait.
*
* @see nachos.machine.Timer#getTime()
*/
public void waitUntil(long x) {
// for now, cheat just to get something working (busy waiting is bad)
// disable interrupt
boolean intStatus = Machine.interrupt().disable();
long wakeTime = Machine.timer().getTime() + x;
// while (wakeTime > Machine.timer().getTime()) {
// KThread.yield1();
// }
// to check if the wakeTime >= WaitUntil called time + x
// System.out.println(wakeTime + ":" + Machine.timer().getTime() + ":" + x);
KThread currentThread = KThread.currentThread();
// create a waitingThread object
WaitingThread waitingThread = new WaitingThread(currentThread, wakeTime);
// place the waitingThread in the waitQueue
waitQueue.add(waitingThread);
// put the current thread to sleep using condition2
// alarmCondition.sleep();
lock.acquire();
alarmCondition.sleep();
lock.release();
// Not using Kthread to put thread to sleep instead using condition2
// KThread.sleep();
// enable interrupt
Machine.interrupt().restore(intStatus);
}
// added WaitingThread
private class WaitingThread implements Comparable<WaitingThread> {
KThread thread;
long wakeTime;
public WaitingThread(KThread thread, long wakeTime) {
this.thread = thread;
this.wakeTime = wakeTime;
}
public void wakeWaitingThread(){
alarmCondition.wake();
}
public int compareTo(WaitingThread thread) {
if (this.wakeTime < thread.wakeTime) {
return -1;
} else if (this.wakeTime > thread.wakeTime) {
return 1;
} else {
return 0;
}
}
}
// created waitQueue
private PriorityQueue<WaitingThread> waitQueue = new PriorityQueue<WaitingThread>();
// create a private Lock called lock.
private Lock lock = new Lock();
// create a private Condition2 called alarmCondition.
private Condition2 alarmCondition = new Condition2(lock);
}
Editor is loading...