``````/* File:       pi-pthread.c
*
* Purpose:    Estimates pi in parallel using the Madhavaâ€“Leibniz series and
*             pthreads. NOTE: the number of intervals should be
*             evenly-divisible by the number of threads.
*
*                 (bonus: try with -O3 ?)
*/

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>

/* We define pi here so we can check and see how accurate our computation is. */
#define PI 3.141592653589793238462643

/** Size of the calculation performed by each thread: */
unsigned long long block_size;

long double *totals;

double get_time(void)
{
struct timeval t;
gettimeofday(&t, NULL);
return t.tv_sec + t.tv_usec / 1000000.0;
}

{
unsigned long rank = (unsigned long) arg;
unsigned long long start = block_size * rank;
unsigned long long end = block_size * rank + block_size;
#ifdef DEBUG
fprintf(stderr, "I am thread %ld calculating range %Ld to %Ld\n",
(long) rank, start, end);
#endif

for (unsigned long long i = start; i < end; ++i) {
if (i % 2 == 0) {
totals[rank] = totals[rank] + (1.0 / ((2.0 * i) + 1));
} else {
totals[rank] = totals[rank] - (1.0 / ((2.0 * i) + 1));
}
}

return NULL;
}

int main(int argc, char *argv[])
{
if (argc <= 1) {
fprintf(stderr, "Usage: %s num-intervals [num-threads]\n", argv[0]);
return EXIT_FAILURE;
}

if (argc < 3) {
} else if (argc >= 3) {
}

unsigned long long intervals = strtoull(argv[1], NULL, 10);
printf("Intervals: %llu\n", intervals);

if (intervals == 0 || num_threads <= 0) {
return 0;
}

double time1 = get_time();

totals = malloc(num_threads * sizeof(long double));
for (int i = 0; i < num_threads; ++i) {
NULL,
((void *) (unsigned long) i));
}

long double total = 0.0;
for (int i = 0; i < num_threads; ++i) {