package nachos.threads; import nachos.machine.*; /** * An implementation of condition variables that disables interrupt()s for * synchronization. * *

* You must implement this. * * @see nachos.threads.Condition */ public class Condition2 { /** * Allocate a new condition variable. * * @param conditionLock the lock associated with this condition * variable. The current thread must hold this * lock whenever it uses sleep(), * wake(), or wakeAll(). */ public Condition2(Lock conditionLock) { this.conditionLock = conditionLock; } /** * Atomically release the associated lock and go to sleep on this condition * variable until another thread wakes it using wake(). The * current thread must hold the associated lock. The thread will * automatically reacquire the lock before sleep() returns. */ public void sleep() { Lib.assertTrue(conditionLock.isHeldByCurrentThread()); conditionLock.release(); boolean intStatus=Machine.interrupt().disable(); waitQueue.waitForAccess(KThread.currentThread()); KThread.sleep(); Machine.interrupt().restore(intStatus); conditionLock.acquire(); } /** * Wake up at most one thread sleeping on this condition variable. The * current thread must hold the associated lock. */ public void wake() { Lib.assertTrue(conditionLock.isHeldByCurrentThread()); boolean intStatus=Machine.interrupt().disable(); KThread a=waitQueue.nextThread(); if(a!=null) a.ready(); Machine.interrupt().restore(intStatus); } /** * Wake up all threads sleeping on this condition variable. The current * thread must hold the associated lock. */ public void wakeAll() { Lib.assertTrue(conditionLock.isHeldByCurrentThread()); boolean intStatus=Machine.interrupt().disable(); while(true) { KThread a=waitQueue.nextThread(); if(a!=null) a.ready(); else break; } Machine.interrupt().restore(intStatus); } private Lock conditionLock; private ThreadQueue waitQueue=ThreadedKernel.scheduler.newThreadQueue(true); }