#include <stdio.h>
#include <omp.h>
#include <stdlib.h>
#include <sys/time.h>

#define MAX_THREADS	512

void *compute_pi (void *);

int sample_points, sample_points_per_thread, num_threads;
double rand_no_x, rand_no_y;


main()
{
	int i; int sum; int seed;
	double computed_pi;

	double start_time, end_time;
	struct timeval tz;
	struct timezone tx;


	printf("Enter number of sample points: ");
	scanf("%d", &sample_points);
	printf("Enter number of threads: ");
        scanf("%d", &num_threads);

	for (num_threads = num_threads; num_threads > 0;
		num_threads /= 2)
	{
 	sum = 0; 

	sample_points_per_thread = sample_points / num_threads;

	gettimeofday(&tz, &tx);
	start_time = (double)tz.tv_sec + (double) tz.tv_usec / 1000000.0;

#pragma omp parallel private(rand_no_x, rand_no_y, seed, i) \
  shared(sample_points, sample_points_per_thread)	reduction(+: sum) num_threads(num_threads)
  { seed = omp_get_thread_num();
  	for (i = 0; i < sample_points_per_thread; i++) {
  		rand_no_x =(double)(rand_r(&seed))/(double)((2<<30)-1);
  		rand_no_y =(double)(rand_r(&seed))/(double)((2<<30)-1);
  	if ((	(rand_no_x - 0.5) * (rand_no_x - 0.5) +
  		  			(rand_no_y - 0.5) * (rand_no_y - 0.5)) < 0.25)
    sum ++;
  }
  }
	gettimeofday(&tz, &tx);
	end_time = (double)tz.tv_sec + (double) tz.tv_usec / 1000000.0;

	computed_pi = 4.0*(double) sum /
		((double)(sample_points));

	
	printf("%d ", num_threads);
	printf("Computed PI = %lf\n", computed_pi);
	printf(" %lf\n", end_time - start_time);
	}
}




