package nachos.threads; import nachos.machine.*; import java.util.LinkedList; /** * An implementation of condition variables that disables interrupt()s for * synchronization. * * <p> * 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 <tt>sleep()</tt>, * <tt>wake()</tt>, or <tt>wakeAll()</tt>. */ 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 <tt>wake()</tt>. The * current thread must hold the associated lock. The thread will * automatically reacquire the lock before <tt>sleep()</tt> returns. */ public void sleep() { Lib.assertTrue(conditionLock.isHeldByCurrentThread()); conditionLock.release(); Machine.interrupt().disable(); count++; waitQueue.waitForAccess(KThread.currentThread()); KThread.sleep(); 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 t = waitQueue.nextThread(); if(t != null) { count--; t.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(); KThread t; while((t = waitQueue.nextThread()) != null) t.ready(); count = 0; Machine.interrupt().restore(intStatus); } public void acquireDonation(KThread t) { if(ThreadedKernel.scheduler instanceof PriorityScheduler) waitQueue.acquire(t); } public int getThreadCount() { return count; } private Lock conditionLock; private ThreadQueue waitQueue = ThreadedKernel.scheduler.newThreadQueue(true); private int count; }