typedef struct {
  int low, high;
} Range;

int isPrime(m) {
  int n, composite;
  n = 3;
  composite = 0;
  while ( (!composite ) && (n*n <= m)) {
    if ( (m%n) == 0) composite = 1;
    n += 2;
  }
  return (!composite);
}

int countPrimes(int l, int u) {
  int i, count;
  count = 0;
  if (l%2 == 0) l++;
  for (i=l; i<=u; i+= 2) {
    if (isPrime(i)) count++;
  }
  return count;
}

int primesInRange(Range * range, int ** count) {
  *count = (int *) malloc(sizeof(int));
  **count = countPrimes(range->low, range->high);
  return (sizeof(int));
}

main(int argc, char *argv[])
{
  Range *range;
  int *x;
  int total, i, lo, hi, numSlaves,grain;

  CmsInit(primesInRange, 100);
  if (argc < 3) {
    CmiPrintf("Usage: countPrimes <from> <To> <> \n");
    CmsExit();
  }
  else
    {
      lo = atoi(argv[1]);
      hi = atoi(argv[2]);
      numSlaves = atoi(argv[3]);
      CmiPrintf("%d, %d, %d\n", lo, hi, numSlaves);
    }
  
  range = (Range *) malloc(sizeof(Range));
  grain  = (hi-lo)/numSlaves;

  for (i=0; i<numSlaves; i++) {
    range->low = i*grain + lo; 
    range->high = (i+1)*grain;
    if (i == (numSlaves-1)) /* the last one gets all the remaining */
    range->high = hi;
    CmsFireTask(i, range, sizeof(Range));
  }
  CmsAwaitResponses();
  
  total = 0;
  for (i=0; i<numSlaves; i++) {
    x = (int *) CmsGetResponse(i);
    total += *x;
  }
  CmiPrintf("The number of Primes in the range [%d:%d] is %d.\n", lo, hi, total);
  CmsExit();
}
