
// illustrates use of a barrier instead of pthread_join() (not
// preferable, just an example)

// the goal of the code is to find the sum of elements in an array

#include <stdio.h>
#include <pthread.h>  // required for threads usage

#define MAX_N 100000000
#define MAX_THREADS 25

// shared variables
int nthreads,  // number of threads (not counting main())
    n,  
    x[MAX_N+1],
    sum = 0;  
pthread_mutex_t sumlock = PTHREAD_MUTEX_INITIALIZER;
// ID structs for the threads
pthread_t id[MAX_THREADS];
pthread_barrier_t barr;

// each worker sums its chunk of x, with x's length n assumed to be a
// multiple of nthreads
void *summer(int tn)  // tn is the thread number (0,1,...)
{  int i, chunksize = n/nthreads;
   int mysum = 0;
   for (i = tn*chunksize; i < (tn+1)*chunksize; i++)
      mysum += x[i];
   pthread_mutex_lock(&sumlock);
   sum += mysum;
   pthread_mutex_unlock(&sumlock);
   pthread_barrier_wait(&barr);
}

main(int argc, char **argv)
{  int nprimes,  // number of primes found 
       i,work;
   n = atoi(argv[1]);
   nthreads = atoi(argv[2]);
   // we'll be having the thread-creating function use the barrier too,
   // so count it in the barrier init
   pthread_barrier_init(&barr,NULL,nthreads+1); 
   for (i = 0; i < n; i++)  
      x[i] = i*i*i % 5;  // just a test
   for (i = 0; i < nthreads; i++)  {
      pthread_create(&id[i],NULL,summer,i);
   }
   pthread_barrier_wait(&barr);
   printf("the array sum was %d\n",sum);
}
