/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗ FILE: arrayloops.c

∗ DESCRIPTION:

∗ Example code demonstrating decomposition of array processing by

∗ distributing loop iterations. A global sum is maintained by a mutex

∗ variable.

∗ LAST REVISED: 02/11/2002 Blaise Barney ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/

#include <pthread.h>
#include <stdio.h>

#define NTHREADS 4 #define ARRAYSIZE 1000000 #define ITERATIONS ARRAYSIZE / NTHREADS

double sum=0.0, a[ARRAYSIZE]; pthread mutex t sum mutex;

void ∗do work(void ∗tid) {

int i, start, ∗mytid, end;

double mysum=0.0;

/∗ Initialize my part of the global array and keep local sum ∗/

mytid = (int ∗) tid;

start = (∗mytid ∗ ITERATIONS);

end = start + ITERATIONS;

  printf ("Thread %d doing iterations %d to %d\n",∗mytid,start,end−1);

for (i=start; i < end ; i++) { a[i] = i ∗ 1.0; mysum = mysum + a[i]; }

/∗ Lock the mutex and update the global sum, then exit ∗/

pthread mutex lock (&sum mutex);

sum = sum + mysum;

pthread mutex unlock (&sum mutex);

pthread exit(NULL); }

int main(int argc, char ∗argv[]) {

int i, start, tids[NTHREADS]; pthread t threads[NTHREADS]; pthread attr t attr;

/∗ Pthreads setup: initialize mutex and explicitly create threads in a

joinable state (for portability). Pass each thread its loop offset ∗/ pthread mutex init(&sum mutex, NULL); pthread attr init(&attr); pthread attr setdetachstate(&attr, PTHREAD CREATE JOINABLE); for (i=0; i<NTHREADS; i++) {

tids[i] = i;

pthread create(&threads[i], &attr, do work, (void ∗) &tids[i]); }

/∗ Wait for all threads to complete then print global sum ∗/ for (i=0; i<NTHREADS; i++) {

pthread join(threads[i], NULL); } printf ("Done. Sum= %e \n", sum);

sum=0.0; for (i=0;i<ARRAYSIZE;i++){ a[i] = i∗1.0; sum = sum + a[i]; } printf("Check Sum= %e\n",sum);

/∗ Clean up and exit ∗/ pthread attr destroy(&attr); pthread mutex destroy(&sum mutex); pthread exit (NULL);

}