// variable sized simple spmd program written by ian a. mason // may 18 @ une #include #include #include #include #include "pvm3.h" #include "pvm_lib.h" #define SELF "e_vsspmd" #define TIDTAG 17 #define TOKTAG 13 int main(int argc, char *argv[]){ int mytid, me, daddy, numt, i, nproc, nchild, *tids , info; long start_time = time(NULL); mytid = pvm_error_check(pvm_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 %s\n", i, pvmErrorCode2String(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_error_check(pvm_initsend(PvmDataDefault), ""); pvm_error_check(pvm_pkint(&nproc, 1, 1), ""); pvm_error_check(pvm_pkint(tids, nproc, 1), ""); pvm_error_check(pvm_pklong(&start_time, 1, 1), ""); info = pvm_error_check(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_error_check(pvm_recv(daddy, TIDTAG), ""); printf("i've heard from daddy\n"); pvm_error_check(pvm_upkint(&nproc, 1, 1), ""); //NB! the child needs to allocate space too!! if((tids = (int *) calloc(nproc, sizeof(int))) == NULL){ fprintf(stderr, "Calloc failed\n"); pvm_exit(); exit(EXIT_FAILURE); } pvm_error_check(pvm_upkint(tids, nproc, 1), ""); pvm_error_check(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_error_check(pvm_initsend(PvmDataDefault), ""); printf("sending token around the ring at time = %ld\n", time(NULL) - start_time); pvm_error_check(pvm_pkint(&token, 1, 1), ""); pvm_error_check(pvm_send(tids[dst], TOKTAG), ""); pvm_error_check(pvm_recv(tids[src], TOKTAG), ""); printf("token arrived back safely at time = %ld\n", time(NULL) - start_time); } else { pvm_error_check(pvm_recv(tids[src], TOKTAG), ""); pvm_error_check(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_error_check(pvm_initsend(PvmDataDefault), ""); pvm_error_check(pvm_pkint(&token, 1, 1), ""); pvm_error_check(pvm_send(tids[dst],TOKTAG), ""); } pvm_exit(); exit(EXIT_SUCCESS); } }