Untitled
unknown
java
2 years ago
4.3 kB
21
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...