/******************************************************/
/*  PVM Example Program                               */
/*  Simple Send and Receive           master1.c       */
/*                                                    */
/******************************************************/

#include <stdio.h>
#include "/usr/pvm3/include/pvm3.h"
#define SLAVENAME "slave1"
#define MAXTASKS 10


main()
{
    int nproc, numt,randnum, i, who, msgtype, nhost;
    int mytid;                  /* my task id */
    int tids[MAXTASKS];		/* slave task ids */
    char data[50];
    struct pvmhostinfo *hostp[MAXTASKS]; /* pointers to host information */

/* Enroll in pvm */
    mytid = pvm_mytid();

/* Set number of slave processes desired */
    printf("Enter the number of tasks to start?  (Max is %d)\n", MAXTASKS);
    scanf("%d",&nproc);

/* Start up slave tasks */  

// If the number of tasks spawned does not match nproc, there's a problem!

    numt = pvm_spawn(SLAVENAME, (char**)0, 0, "", nproc, tids);

/* Error Routine  */
// If there is a problem with spawning tasks, kill everything and quit
    if( numt < nproc ){
       printf("Trouble spawning slaves. Aborting. Error codes are:\n");
       for( i=numt ; i<nproc ; i++ ) {
          printf("TID %d %d\n",i,tids[i]);
       }
       for( i=0 ; i<numt ; i++ ){
          pvm_kill( tids[i] );
       }
       pvm_exit();
       exit();
    }
/* End of Error Routine */
    

/* Begin User Program */

   // establish seed value for a random number stream
   srand(time(0));

/* Broadcast data to each slave task */

   msgtype = 0;		// Arbitrary message identifier
   for (i=0; i < nproc; i++)		// Cycle through all processes
      {
        randnum = rand();		// Generate a random number
	pvm_initsend(PvmDataDefault); 	// Get ready to send message buffer
	pvm_pkint(&randnum, 1, 1); 	// Pack Random Number 
    	pvm_send(tids[i], msgtype);	// Send to identified processor
      }

/* Wait for results from slaves */

    msgtype = 5;  	// This value is arbitrary, just for ID purposes

    for( i=0 ; i<nproc ; i++ )  	// Wait for replies from all processes
      {
    	pvm_recv( -1, msgtype );	// Wait for message of right type
    	pvm_upkint( &who, 1, 1 );	// Find out who sent message
        pvm_upkint(&randnum, 1, 1);	// Unpack Random Number
    	pvm_upkstr( data);     		// Unpack the data string

	// Display results
    	printf("System: %s  Process:  %d  Random: %d\n", data, who, randnum  );  
    }

/* Program Finished - exit PVM before stopping */
    pvm_exit();
}

