/* illustrate token ring synchronization */ #include #include #include #include "pvm3.h" #define TOKEN -9 #define NPROC 16 #define GROUP "thisRing" void dowork(int,int); void bail(int*, int, int); int main(int argc, char**argv){ int n, mytid, tids[NPROC - 1], me; mytid = pvm_mytid(); /* Join a group and if I am the first instance */ /* i.e. me = 0 spawn more copies of myself */ me = pvm_joingroup(GROUP); fprintf(stderr, "me = %d mytid = %d\n", me, mytid); if(me == 0){ n = pvm_spawn("spmd2", NULL, 0, "", NPROC - 1, tids); if(n < NPROC - 1){ bail(tids, NPROC - 1, n); pvm_exit(); exit(EXIT_FAILURE); } } /* Wait for everyone to startup before proceeding. */ pvm_freezegroup(GROUP, NPROC); pvm_barrier(GROUP, NPROC); /*------------------BARRIER----------------------------*/ dowork(me, NPROC); /* program finished leave group and exit pvm */ pvm_lvgroup( GROUP ); pvm_exit(); exit(EXIT_SUCCESS); } /* Simple example passes a token around a ring */ void dowork(int me, int nproc ){ int token, src, dest, count = 1, stride = 1, msgtag = 4; /* Determine neighbors in the ring */ src = pvm_gettid(GROUP, (me == 0 ? NPROC - 1 : me - 1)); dest = pvm_gettid(GROUP, (me == NPROC - 1 ? 0 : me + 1)); if(me == 0){ token = TOKEN; pvm_initsend(PvmDataDefault); pvm_pkint(&token, count, stride); pvm_send(dest, msgtag); pvm_recv(src, msgtag); printf("token ring done\n"); } else { pvm_recv(src, msgtag); pvm_upkint(&token, count, stride); /* Critical Section */ printf( "I'm ring node %d\n", me ); printf( "I'm ring node %d with token %d\n", me, token ); pvm_initsend( PvmDataDefault ); pvm_pkint(&token, count, stride); pvm_send(dest, msgtag); } } /* Shutdown if spawn fails */ void bail(int *tids, int tidmax, int actual){ int i; fprintf(stderr, "Trouble spawning. Aborting. Error codes are:\n"); for(i = actual; i < tidmax; i++){ printf("TID %d %d\n", i, tids[i]); } for(i = 0; i < actual; i++){ pvm_kill(tids[i]); } }