// variable sized simple spmd program written by ian a. mason // may 18 @ une #include <stdlib.h> #include <stdio.h> #include <sys/types.h> #include <time.h> #include "pvm3.h" #define SELF "vsspmd" #define TIDTAG 17 #define TOKTAG 13 int main(int argc, char *argv[]){ int *tids, mytid, me, daddy, numt, i, nproc, nchild, info; long start_time = time(NULL); mytid = pvm_mytid(); daddy = pvm_parent(); if(daddy == PvmNoParent){ /* parent code */ if ((argc != 2) || ((nproc = atoi(argv[1])) <= 0)){ fprintf(stderr, "Usage: %s ntasks\n", argv[0]); pvm_exit(); exit(EXIT_FAILURE); }; nchild = nproc - 1; if((tids = (int *)calloc(nproc, sizeof(int))) == NULL){ fprintf(stderr, "Calloc failed\n"); pvm_exit(); exit(EXIT_FAILURE); } me = 0; tids[0] = mytid; printf("i'm daddy with tid %d\n", tids[0]); printf("spawning %d children at t = %ld\n", nchild, time(NULL) - start_time); numt = pvm_spawn(SELF, &argv[1], 0, "", nchild, &tids[1]); if( numt < nchild){ printf("Aborting. Error codes are:\n"); for( i = numt ; i < nchild ; i++ ) { printf("TID %d %d\n",i,tids[i]); } for( i = 1 ; i < numt ; i++ ){ pvm_kill( tids[i] ); } pvm_exit(); exit(EXIT_FAILURE); } for( i = 1 ; i < nproc ; i++ ) printf("child %d with id %d spawned\n", i, tids[i]); pvm_initsend(PvmDataDefault); pvm_pkint(&nproc, 1, 1); pvm_pkint(tids, nproc, 1); pvm_pklong(&start_time, 1, 1); info = pvm_mcast(&tids[1], nchild, TIDTAG); printf("mcast executed with info = %d\n", info); } else { /* child code */ printf("i'm waiting for daddy\n"); pvm_recv(daddy, TIDTAG); printf("i've heard from daddy\n"); pvm_upkint(&nproc, 1, 1); //NB! the child needs to allocate space too!! tids = (int *) calloc(nproc, sizeof(int)); pvm_upkint(tids, nproc, 1); pvm_upklong(&start_time, 1, 1); /* Determine which slave I am (1 -- nproc-1) */ for( i = 1; i < nproc ; i++ ) if( mytid == tids[i] ){ me = i; break; } printf("i'm child %d with tid %d at time = %ld\n", i, tids[i], time(NULL) - start_time); } /* ring code */ { int token = 58; int dst = ( (me == (nproc - 1)) ? 0 : me + 1 ); int src = ( (me == 0) ? (nproc - 1) : me - 1 ); if( me == 0 ){ pvm_initsend(PvmDataDefault ); printf("sending token around the ring at time = %ld\n", time(NULL) - start_time); pvm_pkint(&token, 1, 1); pvm_send(tids[dst], TOKTAG ); pvm_recv(tids[src], TOKTAG ); printf("token arrived back safely at time = %ld\n", time(NULL) - start_time); } else { pvm_recv(tids[src], TOKTAG ); pvm_upkint(&token, 1, 1); printf("i'm child %d and i got token %d at time = %ld\n", i, token, time(NULL) - start_time); //sleep(1); pvm_initsend(PvmDataDefault ); pvm_pkint(&token, 1, 1); pvm_send(tids[dst],TOKTAG ); } pvm_exit(); exit(EXIT_SUCCESS); } }