#include #include #include #include #define sclock() sclock(self) #define MAX_PHILOSOPHERS 100 #define EATING_TIME 100 #define THINKING_TIME 50 #define REQUESTED 3 #define DIRTY 2 #define CLEAN 1 #define MISSING 0 #define MAXTIME "500" #define RAD 100 #define XBASE 100 #define YBASE 100 #define WIDTH 30 #define WIDTH2 5 #define DF 0 #define numproc 8 #define CIRCLE(X) printf("circle X %d %d %d %d\n", (int) (XBASE + RAD * sin(priority / ((float) numproc) * 6.28)) - (WIDTH/2) , (int) (YBASE+ RAD * cos(priority / ((float) numproc) * 6.28)) - (WIDTH/2), WIDTH, WIDTH) #define LINE(X1,Y1,X2,Y2) printf("line black %d %d %d %d\n", (int) X1, (int) Y1, (int) X2, (int) Y2) #define XP(M) ((XBASE + RAD *sin( ((M + numproc -1) % numproc) / ((float) numproc) * 6.28))) #define YP(M) ((YBASE + RAD * cos(((M + numproc - 1) % numproc) / ((float) numproc) * 6.28))) #define DISTANCE(X1, Y1, X2, Y2) (sqrt(X1 - X2) * (X1 - X2) + (Y1 - Y2) *(Y1 - Y2)) /* #define SCIRCLE(M,D,C) print("circle C %d %d %d %d\n", (int) (XBASE + RAD * sin(((float ) M) / ((float) numproc) * 6.28 + ((6.28 / numproc)/10))) , (int) (YBASE+RAD * cos((((float) M) / ((float) numproc) * 6.28 + ((6.28 / numproc)/10)))) , WIDTH2, WIDTH2) */ void scircle(source, destination, color) int source; int destination; int color; { float d; float xv, xa, xb; float yv, ya, yb; float xpos; float ypos; xa = (float) XP(source), ya = (float) YP(source); xb = (float) XP(destination), yb = (float) YP(destination); d = (xa - xb)*(xa - xb) + (ya -yb)*(ya - yb); d = sqrt(d); xv = (xa - xb) / d; yv = (ya - yb) / d; xpos = ((float) -0.5 * (WIDTH+WIDTH2)) * xv; ypos = ((float) -0.5 * (WIDTH+WIDTH2)) * yv; printf("fork - source %d %f %f\n", source, xa, ya); printf("fork - destinatination %d %f %f\n", destination, xb, yb); xpos = xa + xpos; ypos = ya + ypos; printf("fork - position %f %f\n", xpos, ypos); printf("fork - color %d\n", color); printf("circle black %d %d %d %d\n", (int) xa, (int) ya, WIDTH2, WIDTH2); if (color == 0) { /* Missing fork */ printf("circle white %d %d %d %d\n", (int) xpos, (int) ypos, WIDTH2, WIDTH2); } else if (color == 1) { /* Clean fork */ printf("circle blue %d %d %d %d\n", (int) xpos, (int) ypos, WIDTH2, WIDTH2); } else if (color == 2) { /* Dirty fork */ printf("circle black %d %d %d %d\n", (int) xpos, (int) ypos, WIDTH2, WIDTH2); }; } /* global variables (naughty, naughty!) */ /* user-defined messages */ message Fork {ename id;}; message Request {ename id;}; message Hello {ename id;int priority;}; /* system defined messages */ message init_philosopher {int ids[MAX_PHILOSOPHERS]; ename neighbors[MAX_PHILOSOPHERS];int neighbors_N;}; entity philosopher { int priority} { /* communication partners */ ename neighbors[MAX_PHILOSOPHERS]; int ids[MAX_PHILOSOPHERS]; int neighbors_N; /* local variables */ /* user variables */ int meal_time; int forks[MAX_PHILOSOPHERS]; int forks_i_have; int i, j; int mvpec0; double myid; /* double numproc; */ /* Default Initialization */ myid = (double) priority; /* numproc = 5.0; */ wait until mtype(init_philosopher) { for (mvpec0 = 0; mvpec0 < MAX_PHILOSOPHERS; mvpec0++) { neighbors[mvpec0] = msg.init_philosopher.neighbors[mvpec0]; ids[mvpec0] = msg.init_philosopher.ids[mvpec0]; }; neighbors_N = msg.init_philosopher.neighbors_N; } /* Entity Body */ /* initialization */ for (i = 0; i < neighbors_N; i++) { forks[i] = MISSING; invoke neighbors[i] with Hello{self, priority}; } for (i = 0; i < neighbors_N; i++) wait until mtype (Hello) { for (j = 0; j < neighbors_N; j++) if (ename_cmp(neighbors[j],msg.Hello.id)) if (priority < msg.Hello.priority) { forks[j] = DIRTY; /* Draw dirty fork */ scircle((int) myid,ids[j],2); }; } /* user-written body */ while (1) { /* thinking */ print("Philosopher %d is thinking at time %d.", priority, sclock()); CIRCLE(blue); /* set random thinking time */ meal_time = sclock() + (int)(THINKING_TIME*drand48()+1); while (1) { wait (meal_time - sclock()) until { mtype (Request) { for (i = 0; i < neighbors_N; i++) if (ename_cmp(neighbors[i],msg.Request.id)) { forks[i] = MISSING; /* Sending of fork */ scircle((int) myid,ids[i],0); invoke neighbors[i] with Fork{self} after 1; /* Draw clean fork at neightbor */ scircle(ids[i], (int) myid, 1); } } or mtype (timeout) break; } } /* hungry */ print("Philosopher %d is hungry at time %d.", priority, sclock()); CIRCLE(red); /* request forks */ forks_i_have = 0; for (i = 0; i < neighbors_N; i++) if (forks[i] != MISSING) forks_i_have++; else invoke neighbors[i] with Request{self} after 1; /* wait for forks */ while (forks_i_have < neighbors_N) { wait until { mtype (Fork) { /* I just got a fork */ for (i = 0; i < neighbors_N; i++) if (ename_cmp(neighbors[i],msg.Fork.id)) { /* Draw the fork I just got */ /* scircle((int) myid,i,1); */ forks[i] = CLEAN; forks_i_have++; } } or mtype (Request) { /* I need a fork */ for (i = 0; i < neighbors_N; i++) if (ename_cmp(neighbors[i],msg.Request.id)) if (forks[i] == DIRTY) { forks[i] = MISSING; /* Sending fork */ /* Erase fork that I have */ scircle((int) myid,ids[i],0); invoke neighbors[i] with Fork{self} after 1; scircle(ids[i], (int) myid,1); /* Requesting fork */ invoke neighbors[i] with Request{self} after 2; forks_i_have--; } else /* fork is CLEAN, remember that it was requested */ forks[i] = REQUESTED; } } } /* eating */ print("Philosopher %d is eating at time %d.", priority, sclock()); CIRCLE(green); hold((int)(EATING_TIME*drand48()+1)); /* deliver forks that were requested while i was hungry */ for (i = 0; i < neighbors_N; i++) if (forks[i] == REQUESTED) { scircle((int) myid,ids[i],0); invoke neighbors[i] with Fork{self} after 1; scircle(ids[i], (int) myid,1); forks[i] = MISSING; } else forks[i] = DIRTY; scircle((int) myid,ids[i],2); } } entity driver{ int argc, char ** argv} { /* local variables */ /* entity objects */ ename philosophers[MAX_PHILOSOPHERS]; ename neighbors[MAX_PHILOSOPHERS]; int ids[MAX_PHILOSOPHERS]; int i; /* User Initialization, part 1 */ maxclock(MAXTIME); printf("string 10 230 :Blue = Philosopher thinking\n"); printf("string 10 245 :Red = Philosopher hungry\n"); printf("string 10 260 :Green = Philosopher eating\n"); /* Entity Creation */ for (i = 0; i < numproc; i++) { philosophers[i] = new philosopher{i}; LINE((XBASE + RAD *sin( ((i + numproc -1) % numproc) / ((float) numproc) * 6.28)), (int) (YBASE + RAD * cos(((i + numproc - 1) % numproc) / ((float) numproc) * 6.28)), (XBASE + RAD *sin(((i) % numproc) / ((float) numproc) * 6.28)), (int) (YBASE + RAD * cos(((i) % numproc) / ((float) numproc) * 6.28))); } for (i = 0; i < numproc; i++) { neighbors[0] = philosophers[ ( i + numproc - 1) % numproc ]; ids[0] = (i + numproc - 1) % numproc; neighbors[1] = philosophers[ ( i+ 1) % numproc]; ids[1] = (i + 1) % numproc; invoke philosophers[i] with init_philosopher{ids, neighbors, 2}; } /* User Initialization, part 2 */ }