p1/threads/Boat.java

257 lines
5.0 KiB
Java

package nachos.threads;
import nachos.ag.BoatGrader;
public class Boat
{
static BoatGrader bg;
public static void selfTest()
{
BoatGrader b = new BoatGrader();
System.out.println("\n ***Testing Boats with only 2 children***");
begin(100, 4, b);
/*
System.out.println("\n ***Testing Boats with 2 children, 1 adult***");
begin(1, 2, b);
*/
/*
System.out.println("\n ***Testing Boats with 3 children, 3 adults***");
begin(3, 3, b);
*/
}
public static void begin( int adults, int children, BoatGrader b )
{
// Store the externally generated autograder in a class
// variable to be accessible by children.
bg=b;
// Instantiate global variables here
// Create threads here. See section 3.4 of the Nachos for Java
// Walkthrough linked from the projects page.
//
num_adults=adults;
num_children=children;
KThread t_adults[]=new KThread[adults];
KThread t_children[]=new KThread[children];
for(int i=0;i<adults;i++)
{
Runnable r = new Runnable()
{
public void run()
{
AdultItinerary();
}
};
t_adults[i]=new KThread(r);
t_adults[i].fork();
}
for(int i=0;i<children;i++)
{
Runnable r = new Runnable()
{
public void run()
{
ChildItinerary();
}
};
t_children[i]=new KThread(r);
t_children[i].fork();
}
while(true)
{
mainLock.acquire();
mainCond.sleep();
mainLock.release();
numLock.acquire();
if(num_adults==passed_adults&&num_children==passed_children)
return;
numLock.release();
}
}
static void AdultItinerary()
{
bg.initializeAdult(); //Required for autograder interface. Must be the first thing called.
//DO NOT PUT ANYTHING ABOVE THIS LINE.
/* This is where you should put your solutions. Make calls
to the BoatGrader to show that it is synchronized. For
example:
bg.AdultRowToMolokai();
indicates that an adult has rowed the boat across to Molokai
*/
int position=0;
while(true)
{
if(position==0)
{
adult0.P();
ship0.P();
bg.AdultRowToMolokai();
numLock.acquire();
passed_adults+=1;
numLock.release();
mainLock.acquire();
mainCond.wake();
mainLock.release();
ship1.V();
adult0.V();
position=1;
condLock1.acquire();
cond1.wake();
condLock1.release();
}
else
{
adult1.P();
while(true)
{
ship1.P();
numLock.acquire();
int x=passed_children;
numLock.release();
if(x==0)
break;
else
{
ship1.V();
condLock1.acquire();
cond1.sleep();
condLock1.release();
}
}
bg.AdultRowToOahu();
numLock.acquire();
passed_adults-=1;
numLock.release();
ship0.V();
adult1.V();
position=0;
}
}
}
static void ChildItinerary()
{
bg.initializeChild(); //Required for autograder interface. Must be the first thing called.
//DO NOT PUT ANYTHING ABOVE THIS LINE.
int position=0;
while(true)
{
if(position==0)
{
int type=0;
child0.P();
mutex1.acquire();
type=waiting_children;
waiting_children+=1;
mutex1.release();
if(type==0)
{
diff.speak(0);
bg.ChildRowToMolokai();
}
else
{
ship0.P();
diff.listen();
bg.ChildRideToMolokai();
mutex1.acquire();
waiting_children=0;
mutex1.release();
numLock.acquire();
passed_children+=2;
numLock.release();
mainLock.acquire();
mainCond.wake();
mainLock.release();
child0.V();
child0.V();
ship1.V();
}
position=1;
}
else
{
child1.P();
ship1.P();
bg.ChildRowToOahu();
numLock.acquire();
passed_children-=1;
numLock.release();
ship0.V();
child1.V();
position=0;
}
}
}
static void SampleItinerary()
{
// Please note that this isn't a valid solution (you can't fit
// all of them on the boat). Please also note that you may not
// have a single thread calculate a solution and then just play
// it back at the autograder -- you will be caught.
System.out.println("\n ***Everyone piles on the boat and goes to Molokai***");
bg.AdultRowToMolokai();
bg.ChildRideToMolokai();
bg.AdultRideToMolokai();
bg.ChildRideToMolokai();
}
static int boatPosition=0;
static int num_adults=0;
static int num_children=0;
static int passed_adults=0;
static int passed_children=0;
static Lock mutex1=new Lock();
static int waiting_children=0;
static Lock numLock=new Lock();
static Lock boatLock=new Lock();
static Lock mainLock=new Lock();
static Condition mainCond=new Condition(mainLock);
static Lock condLock0=new Lock();
static Condition cond0=new Condition(condLock0);
static Lock condLock1=new Lock();
static Condition cond1=new Condition(condLock1);
static Semaphore child0=new Semaphore(2);
static Semaphore adult0=new Semaphore(1);
static Semaphore ship0=new Semaphore(1);
static Semaphore child1=new Semaphore(1);
static Semaphore adult1=new Semaphore(1);
static Semaphore ship1=new Semaphore(0);
static Communicator diff=new Communicator();
}