
#include <stdio.h>
#include "/usr/include/pvm3.h"
#define OUT 99
#define BACK 666
#define MAXNODES 4	// Maximum Nodes in Chain
#define MAXPROCESSES 1	// Maximum processes
main()
{
    int nproc,		// Number of processes
        numtasks,	// Number of tasks
        who, 		// Who sent message 
        last,		// Last leaf in tree
        count,		// Counter for Nth node 
        parent,		// Parent Node
        mytid;     	// My Task ID 

    FILE *fp;           // Files for debugging
    char s[80];         // String for file name

    int tids[MAXPROCESSES];	// Array of Tasks 
    struct pvmhostinfo *hostp[MAXPROCESSES]; // Environment Variables
    nproc = MAXPROCESSES;  // Check for input error 
    count = 0;

    // Enroll in pvm 
    mytid = pvm_mytid(); 	// Get my task ID
    parent = pvm_parent();	// Get Parent ID

    printf("Noparent = %d \n", PvmNoParent);

    if (parent == PvmNoParent) //  This is a First Time Call 
     {
      printf("Starting first task.\n"); // Spawning Task t make a node.
      numtasks = pvm_spawn("tree2", (char**)0, 0, "", nproc, tids);

      sprintf(s,"/home/atlas1/dhyatt/pvm3/bin/LINUX/debug/file.%dA",mytid);
      fp = fopen(s, "w");
      fprintf(fp, "My task ID:  %d   Parent:  %d \n", mytid, parent);
      fclose(fp);
      
      who = tids[count];  // Who is first node?
      printf("Sending data: %d  %d \n", count, who);
      count++;

      //  Send Message OUT to first node
      pvm_initsend(PvmDataDefault);  	// Init buffer
      pvm_pkint(&count, 1, 1);    	// Pack Current count 
      pvm_pkint(&mytid, 1, 1);		// Pack My ID 
      pvm_send(who, OUT); 		// Send message 

      // Wait for results from spawned tasks in tree
      printf("Waiting to receive\n");
      pvm_recv( -1, BACK );		// Wait for message
      pvm_upkint( &count, 1, 1 );	// Get final count 
      pvm_upkint( &last, 1, 1);		// Last node in tree
      pvm_upkint( &who, 1, 1);		// Who sent message 
      
      printf("Count:  %d  Last:  %d   Who: %d\n", count, last, who);  
     }

    else   // This is not the the first node, but a subnode.
      {
       // Receive Message being sent OUT from Parent Node

       pvm_recv( -1, OUT );		// Wait for message
       pvm_upkint( &count, 1, 1 );	// Get Current Count 
       pvm_upkint(&who, 1, 1);		// Who sent message 

       sprintf(s,"/home/atlas1/dhyatt/pvm3/bin/LINUX/debug/file.%dB",mytid);
       fp = fopen(s, "w");
       fprintf(fp, "My task ID:  %d   Count: %d   Who:  %d \n", 
                                                  mytid, count, who);
       fclose(fp);

       if (count < MAXNODES)    // Have we reached the last node?
         {
          // If not, make new Nodes
          numtasks = pvm_spawn("tree2", (char**)0, 0, "", nproc, tids);
          count++;

          // Send Message OUT to Child Node
          pvm_initsend(PvmDataDefault);	// Init buffer
          pvm_pkint(&count, 1, 1);    	// Pack Current count 
          pvm_pkint(&mytid, 1, 1);	// Pack My ID 
          pvm_send(tids[0], OUT); 	// Send message 

        
          // Wait to Receive Message BACK from Child Node
          pvm_recv( -1, BACK );     	// Wait for message
          pvm_upkint( &count, 1, 1 );  	// Get count
          pvm_upkint( &last, 1, 1);	// Get last node in tree
          pvm_upkint( &who, 1, 1 );    	// Get ID of sender

          sprintf(s,"/home/atlas1/dhyatt/pvm3/bin/LINUX/debug/file.%dC",mytid);
          fp = fopen(s, "w");
          fprintf(fp, "My task ID:  %d   Count:  %d   Who %d:  \n", 
                                                     mytid, count, who);
          fclose(fp);

          // Send Message BACK to Parent Node
          pvm_initsend(PvmDataDefault);	// Init buffer
          pvm_pkint(&count, 1, 1);    	// Pack Current Count 
          pvm_pkint(&last, 1, 1);	// Pack Last Node 
          pvm_pkint(&mytid, 1, 1);	// Pack My ID 
          pvm_send(parent, BACK);     	// Send message 
        }

       else   // I have reached a Leaf.  Now send Messages BACK.
         {

          sprintf(s,"/home/atlas1/dhyatt/pvm3/bin/LINUX/debug/file.%dD",mytid);
          fp = fopen(s, "w");
          fprintf(fp, "LAST!!! My task ID:  %d   Count:  %d   Who %d:  \n", 
                                                            mytid, count, who);
          fclose(fp);

          // Send Message BACK to parent nodes
          pvm_initsend(PvmDataDefault);  // Initialize
          pvm_pkint(&count, 1, 1);   // Current count
          pvm_pkint(&mytid, 1, 1);   // I am the Last Node 
          pvm_pkint(&mytid, 1, 1);   // Identify myself
          pvm_send(parent, BACK); // Send back to master
          }
       }
        
   

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

