/* 
 * slave for dynamic task creation
 */

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <math.h>
#include <mpi.h>

#define TAG_WORK         1
#define TAG_RESULT       2

long calc(long total) {
   /* 
    * compute total random points in the unit square
    * and return the number of hits in the sector (x*x + y*y < 1)
    */

   double  x, y;                     /* random coordinates */
   long    hits = 0;                 /* number of hits */
   long     i;
   
   /* initialize random generator (otherwise all return the same result!) */
   srand(getpid());
   
   for(i=0; i<total; i++)
   {
      x = ((double) rand())/RAND_MAX;
      y = ((double) rand())/RAND_MAX;
      
      if ( x*x + y*y <= 1.0 )
      {
	 hits++;
      }
   }

   return(hits); 
}


void main(int argc, char *argv[]) {

  long         mytotal, myhits, totalhits;
  MPI_Status   status;
  MPI_Comm     parentcomm;  /* intercomm */

  /* start MPI */
  MPI_Init(&argc, &argv);

  /* get communicator for master */
  MPI_Comm_get_parent(&parentcomm);
  if (parentcomm == MPI_COMM_NULL) {
    printf("No parent - Aborting!\n");
    MPI_Abort(MPI_COMM_WORLD, -1);
  }

  /* get work from master */
  MPI_Bcast(&mytotal, 1, MPI_LONG, 0, parentcomm);

  /*  compute partial results */
  myhits = calc(mytotal);

  /* send result to master */
  MPI_Reduce(&myhits, &totalhits, 1, MPI_LONG, MPI_SUM, 0, parentcomm);
  
  MPI_Finalize();
}