// Round Robin Slave Program  ... Pass it On

#include <stdio.h>
#include "/usr/pvm3/include/pvm3.h"
#define MAX 10		// Maximum processes

main()
{   int nproc;		// Number of processes
    int i;		// Loop variable
    int who,		// Who sent to me 
        parent,		// Original parent
        msgtype, 	// Message type
        count;		// Counter for Nth pass

    int mytid;    	// My Task ID
    int tids[MAX];	// Array of Slave Tasks
    struct pvmhostinfo *hostp[MAX]; // Host info 

    FILE *fp;		// File for debugging
    char s[50]; 	// String for file name

// Enroll in pvm 
    mytid = pvm_mytid(); // What is my ID

// Debugging approach: Create string, append ID 
// to file name. This is necessary since slaves
// can't print to screen or use same file names.

    sprintf(s,"pvm3/bin/LINUX/debug/file.%d",mytid);	// Make string
    fp = fopen(s, "w"); 				// Open file

    msgtype = 99;  	// Message type for passing data
    fprintf(fp, "My task ID:  %d  \n", mytid);	

// Unpack data sent from another process
    pvm_recv( -1, msgtype );	 // Wait for message 
    pvm_upkint( &count, 1, 1 );	 // Get count
    pvm_upkint( &nproc, 1, 1 );	 // Get number of processes 
    pvm_upkint( &who, 1, 1 );    // Get ID of sender
    pvm_upkint( tids, nproc, 1); // Unpack Task IDs

// Print data received from previous process
    fprintf(fp, "Count:  %d   From:  %d \n", count, who);
    fprintf(fp,"Task IDs\n");
    for (i=0; i < nproc; i++) {
     fprintf(fp, "Task[ %d ]: %d\n", i, tids[i]);
    }

// Print out parent and current IDs, and then close file
    parent = pvm_parent();
    fprintf(fp, "Parent:  %d \n", parent );
    fclose(fp);

// If we haven't finished passing, increment counter and pass it on.
    count++;
    if (count < nproc) {
       msgtype = 99;
       pvm_initsend(PvmDataDefault); // Initialize
       pvm_pkint(&count, 1, 1);   // Current count 
       pvm_pkint(&nproc, 1, 1);   // Number of processes 
       pvm_pkint(&mytid, 1, 1);   // Identify myself
       pvm_pkint(tids, MAX, 1);   // Array of Task IDs 
       pvm_send(tids[count], msgtype); // Send message 
   }
    else{		// Else report back to master
       msgtype = 666;
       pvm_initsend(PvmDataDefault);  // Initialize 
       pvm_pkint(&count, 1, 1);   // Current count 
       pvm_pkint(&mytid, 1, 1);   // Identify myself
       pvm_send(parent, msgtype); // Send back to master
      }

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

