
#include <stdio.h>
#include "pvm3.h"

  /* The student type is just for making things easier for me:
     by keeping the student's information with their grade, we
     can send their index to the child process. */
struct student_tag {
  char first[20], last[20];
  int* grade;
  int average;
};
typedef struct student_tag student_type;
  
int main (int argc, char* argv[]) {

    /* Pertinant info */
  student_type student[6];
  int ave, i, j;
  char tmp[100];
  int *temp_grades;
  char filename[256];
  FILE *input;

    /* Process information */
  int my_tid, tids[32];
  int nhost, narch, num_spawned;
  struct pvmhostinfo *hostp;

    /* Buffer information */
  char buf[32];
  int bufnum, msgtype;

    /* Get info from command line */
  if (argc != 2) {
    printf("Filename not specified.\n");
    exit(1);
  }
  strcpy(filename, argv[1]);

    /* Open the file for reading */
  if ((input = fopen(filename, "r")) == NULL) {
    fprintf(stderr, "Error opening %s\n", filename);
    exit(1);
  }

    /* Read in the contents of the file */
  for(i=0; fgets(tmp, sizeof(tmp), input); i++) {

      /* Allocate memory for the grade array */     
    temp_grades = (int*)malloc(sizeof(int) * 7);

      /* Read in first and last name and grades (yes it's messy) */
    sscanf(tmp, "%s%s%d%d%d%d%d%d%d", 
	student[i].first, 
	student[i].last,
	&temp_grades[0],
	&temp_grades[1],
	&temp_grades[2],
	&temp_grades[3],
	&temp_grades[4],
	&temp_grades[5],
	&temp_grades[6]);

      /* Assign them to the student array */
    student[i].grade = temp_grades;
  }

    /* Start PVM stuff */

    /* Get my task id */ 
  my_tid = pvm_mytid();

    /* Get virtual machine configuration */
  pvm_config(&nhost, &narch, &hostp);

    /* Start up child processes */
  num_spawned = pvm_spawn("ave_slave", 0, PvmTaskDefault, "", 6, tids);
  printf("%d spawned.\n", num_spawned);
  if (num_spawned != 6) {
    fprintf(stderr, "Wrong number of spawned children\n");
    exit(1);
  }
    /* Send the grades to the children */
  for (i=0; i<num_spawned; i++) {
      /* initialize the buffers */
    pvm_initsend(PvmDataDefault);
      /* pack the index */
    pvm_pkint(&i, 1, 1);
      /* pack the array */
    pvm_pkint(student[i].grade, 7, 1);
      /* Send off the info */
    pvm_send(tids[i], 5);
    printf("Sent %s to %d\n", student[i].first, tids[i]);
  }

  printf("\nResults:\n");

    /* intercept the results */
  for(i=0; i<num_spawned; i++) {
    pvm_recv(-1, 4);
    pvm_upkint(&j, 1, 1);
    pvm_upkint(&ave, 1, 1);
    printf("%s(%d) = %d\n", student[j].first, j, ave);
  }
}
