public class Barrier extends Thread {
threadinfo[] tinfo;
int numthreads;
+ GameMap[][] land;
+ int maxage;
+ int rows;
+ int cols;
- public Barrier(int n, threadinfo[] tinfo) {
- numthreads=n;
- this.tinfo=tinfo;
+ public Barrier(int n, threadinfo[] tinfo, GameMap[][] land, int maxage, int rows, int cols) {
+ this.land=land;
+ this.maxage=maxage;
+ this.rows=rows;
+ this.cols=cols;
+ this.numthreads=n;
+
+ this.tinfo=global new threadinfo[n];
}
/**
** @param rows The number of rows in the map
** @param cols The number of columns in the map
**/
- public void updateAge(GameMap[][] land, int maxage, int rows, int cols) {
+ public void updateAge() {
int countTrees = 0;
//System.out.println("updateAge -> maxAge : "+maxage + " rows : " + rows + " cols : "+ cols);
for(int i = 0; i<rows; i++) {
// System.println("Tree count= "+countTrees);
}
- public static void enterBarrier(int threadid, threadinfo[] tinfo, int numthreads) {
+ public static void enterBarrier(Barrier b, int threadid) {
+ threadinfo tinfo[];
+ int numthreads;
int x;
atomic {
- tinfo[threadid].counter++;
- x = tinfo[threadid].counter;
+ /* This transaction updates the counter...we really want threadinfo objects to be local, so we allocate the first time through */
+ numthreads=b.numthreads;
+ tinfo=b.tinfo;
+ if (tinfo[threadid]==null)
+ tinfo[threadid]=global new threadinfo();
+ x = (++tinfo[threadid].counter);
+ tinfo[threadid].status=0;
}
- for(int i=0; i<numthreads; i++) {
- if(threadid == i) {
- continue;
- }
- boolean check = false;
- atomic {
- if(tinfo[i].status != -1) {
- if(tinfo[i].counter >= tinfo[threadid].counter) {
- check = true;
- }
- } else {
- check = true;
- }
- }
- if(!check) {
- int status = Thread.getStatus(i);
- if(status==-1) {//Thread is dead
- atomic {
- tinfo[i].status = -1;
- }
- //System.out.println("DEBUG -> Dead\n");
- continue;
- }
- int y;
- atomic {
- y=tinfo[i].counter;
- }
+ boolean cont=true;
+ int count=0;
- //System.printString("i= " + i + " i's count= " + y + " threadid= " + threadid + " mycount= " + x);
+ /* Here we see if we are the first non-failed machine...if so, we operate the barrier...if not we wait for our signal */
+ while(cont&&count!=threadid) {
+ if (Thread.getStatus(count)==-1) {
+ count++;
+ } else {
+ atomic {
+ if (tinfo[threadid].status==1)
+ cont=false;
+ }
+ }
+ }
- while(y<x && (Thread.getStatus(i) != -1)) {
- //Wait for 100 microseconds
+ if (count==threadid) {
+ /* We are the first non-failed machine...*/
+ int waitingon=numthreads-threadid-1;
+ boolean waiting[]=new boolean[waitingon];
+
+ while(waitingon>0) {
+ //we are doing the barrier
+ for(int i=threadid+1; i<numthreads; i++) {
+ if (!waiting[i-threadid-1]) {
+ atomic {
+ if(tinfo[i]!=null && tinfo[i].counter == tinfo[threadid].counter) {
+ //this one is done
+ waitingon--;
+ waiting[i-threadid-1]=true;
+ } else if (Thread.getStatus(i)==-1) {
+ waitingon--;
+ waiting[i-threadid-1]=true;
+ }
+ }
+ }
+ }
+ if (waitingon>0) //small sleep here
sleep(100);
- atomic {
- y = tinfo[i].counter;
- }
- }
+ }
+ //everyone has reached barrier
+ atomic {
+ //update map
+ b.updateAge();
+ // }
+ //think a single transaction is fine here....
+ // atomic {
+ for(int i=threadid+1; i<numthreads; i++) {
+ if (tinfo[i]!=null)
+ tinfo[i].status=1;
+ }
}
}
- return;
}
}
status = 0;
}
}
-
public void run() {
int id, nthreads;
- threadinfo[] mytinfo;
+ Barrier mybarr;
atomic {
id = threadid;
- mytinfo = barr.tinfo;
nthreads = numThreads;
+ mybarr=barr;
}
Random rand = new Random(id);
atomic {
doOneMove(land, gamer);
}
- if((i&15) == 0 && id == 0) { //same as i%AGEUPDATETHRESHOLD
- /* Update age of all trees in a Map */
- atomic {
- barr.updateAge(land, MAXAGE, ROW, COLUMN);
- }
- }
- Barrier.enterBarrier(id,mytinfo,nthreads);
+ Barrier.enterBarrier(mybarr,id);
}
fi = System.currentTimeMillis();
}
atomic {
- mybarr = global new Barrier(numThreads, tinfo);
world = global new GameMap[ROW][COLUMN];
+ mybarr = global new Barrier(numThreads, tinfo, world, MAXAGE, ROW, COLUMN);
int i, j;
for (i = 0; i < ROW; i++) {
for (j = 0; j < COLUMN; j++) {