Finished Part 1 and 2 with naive testing
parent
33ebdf5cfd
commit
a7b419fbb1
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -20,8 +20,9 @@ public class Condition2 {
|
|||
* lock whenever it uses <tt>sleep()</tt>,
|
||||
* <tt>wake()</tt>, or <tt>wakeAll()</tt>.
|
||||
*/
|
||||
public Condition2(Lock conditionLock) {
|
||||
this.conditionLock = conditionLock;
|
||||
public Condition2(Lock conditionLock)
|
||||
{
|
||||
this.conditionLock = conditionLock;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -30,29 +31,48 @@ public class Condition2 {
|
|||
* 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());
|
||||
public void sleep()
|
||||
{
|
||||
Lib.assertTrue(conditionLock.isHeldByCurrentThread());
|
||||
|
||||
conditionLock.release();
|
||||
|
||||
conditionLock.acquire();
|
||||
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());
|
||||
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());
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -193,6 +193,10 @@ public class KThread {
|
|||
|
||||
|
||||
currentThread.status = statusFinished;
|
||||
|
||||
currentThread.condLock.acquire();
|
||||
currentThread.joinCondition.wakeAll();
|
||||
currentThread.condLock.release();
|
||||
|
||||
sleep();
|
||||
}
|
||||
|
@ -277,6 +281,14 @@ public class KThread {
|
|||
|
||||
Lib.assertTrue(this != currentThread);
|
||||
|
||||
if(status==statusFinished) return;
|
||||
else
|
||||
{
|
||||
condLock.acquire();
|
||||
joinCondition.sleep();
|
||||
condLock.release();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -381,30 +393,98 @@ public class KThread {
|
|||
Lib.assertTrue(this == currentThread);
|
||||
}
|
||||
|
||||
private static class PingTest implements Runnable {
|
||||
PingTest(int which) {
|
||||
this.which = which;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
for (int i=0; i<5; i++) {
|
||||
System.out.println("*** thread " + which + " looped "
|
||||
+ i + " times");
|
||||
currentThread.yield();
|
||||
}
|
||||
}
|
||||
private static class PingTest implements Runnable
|
||||
{
|
||||
PingTest(int which,KThread other)
|
||||
{
|
||||
this.which=which;
|
||||
this.other=other;
|
||||
}
|
||||
|
||||
public void run()
|
||||
{
|
||||
if(other!=null) other.join();
|
||||
if(other!=null) other.join();
|
||||
for(int i=0;i<5;i++)
|
||||
{
|
||||
System.out.println("*** thread " + which + " looped " + i + " times");
|
||||
currentThread.yield();
|
||||
}
|
||||
}
|
||||
|
||||
private int which;
|
||||
private int which;
|
||||
private KThread other;
|
||||
}
|
||||
|
||||
private static class Condition2Test implements Runnable
|
||||
{
|
||||
Condition2Test(int id)
|
||||
{
|
||||
this.id=id;
|
||||
this.wakeMode=-1;
|
||||
}
|
||||
Condition2Test(int id,int wakeMode)
|
||||
{
|
||||
this.id=id;
|
||||
this.wakeMode=wakeMode;
|
||||
}
|
||||
public void run()
|
||||
{
|
||||
if(id==0)
|
||||
{
|
||||
for(int i=0;;i++)
|
||||
{
|
||||
if(i%100==0)
|
||||
{
|
||||
cond2Lock.acquire();
|
||||
if(wakeMode==0) cond2.wake();
|
||||
else cond2.wakeAll();
|
||||
cond2Lock.release();
|
||||
}
|
||||
System.out.println("Main: "+i);
|
||||
currentThread.yield();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int i=0;;i++)
|
||||
{
|
||||
cond2Lock.acquire();
|
||||
cond2.sleep();
|
||||
cond2Lock.release();
|
||||
System.out.println("Thread "+id+" awakened! i="+i);
|
||||
currentThread.yield();
|
||||
}
|
||||
}
|
||||
}
|
||||
private int id;
|
||||
private int wakeMode;
|
||||
private static Lock cond2Lock=new Lock();
|
||||
private static Condition2 cond2=new Condition2(cond2Lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether this module is working.
|
||||
*/
|
||||
public static void selfTest() {
|
||||
Lib.debug(dbgThread, "Enter KThread.selfTest");
|
||||
|
||||
new KThread(new PingTest(1)).setName("forked thread").fork();
|
||||
new PingTest(0).run();
|
||||
//new KThread(new PingTest(1)).setName("forked thread").fork();
|
||||
|
||||
//Test for KThread2.join()
|
||||
/*
|
||||
KThread t1=new KThread(new PingTest(1,null)).setName("forked thread");
|
||||
t1.fork();
|
||||
new PingTest(0,t1).run();
|
||||
*/
|
||||
|
||||
//Test for Condition2
|
||||
new KThread(new Condition2Test(1)).fork();
|
||||
new KThread(new Condition2Test(2)).fork();
|
||||
new KThread(new Condition2Test(3)).fork();
|
||||
new KThread(new Condition2Test(4)).fork();
|
||||
new Condition2Test(0,1).run();
|
||||
|
||||
}
|
||||
|
||||
private static final char dbgThread = 't';
|
||||
|
@ -444,4 +524,7 @@ public class KThread {
|
|||
private static KThread currentThread = null;
|
||||
private static KThread toBeDestroyed = null;
|
||||
private static KThread idleThread = null;
|
||||
|
||||
public Lock condLock=new Lock();
|
||||
private Condition joinCondition=new Condition(condLock);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue