/* matrix summation using pthreads usage on Solaris: gcc matrix.sum.c -lpthread -lposix4 a.out size numWorkers */ #include #include #define SHARED 1 #define MAXSIZE 10000 /* maximum matrix size */ #define MAXWORKERS 4 /* maximum number of workers */ pthread_mutex_t barrier; /* mutex lock for the barrier */ pthread_cond_t go; /* condition variable for leaving */ int numWorkers; int numArrived = 0; /* number who have arrived */ /* a reusable counter barrier */ void Barrier() { pthread_mutex_lock(&barrier); numArrived++; if (numArrived == numWorkers) { numArrived = 0; pthread_cond_broadcast(&go); } else pthread_cond_wait(&go, &barrier); pthread_mutex_unlock(&barrier); } int size, stripSize; /* assume size is multiple of numWorkers */ int sums[MAXWORKERS]; int matrix[MAXSIZE][MAXSIZE]; void *Worker(void *); /* read command line, initialize, and create threads */ int main(int argc, char *argv[]) { int i, j; pthread_attr_t attr; pthread_t workerid[MAXWORKERS]; /* set global thread attributes */ pthread_attr_init(&attr); pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); /* initialize mutex and condition variable */ pthread_mutex_init(&barrier, NULL); pthread_cond_init(&go, NULL); /* read command line */ size = atoi(argv[1]); numWorkers = atoi(argv[2]); stripSize = size/numWorkers; /* initialize the matrix */ for (i = 0; i < size; i++) for (j = 0; j < size; j++) matrix[i][j] = 1; /* create the workers, then exit */ for (i = 0; i < numWorkers; i++) pthread_create(&workerid[i], &attr, Worker, (void *) i); pthread_exit(NULL); } /* Each worker sums the values in one strip of the matrix. After a barrier, worker(0) computes and prints the total */ void *Worker(void *arg) { int myid = (int) arg; int total, i, j, first, last; printf("worker %d (pthread id %d) has started\n", myid, pthread_self()); /* determine first and last rows of my strip */ first = myid*stripSize; last = first + stripSize - 1; /* sum values in my strip */ total = 0; for (i = first; i <= last; i++) for (j = 0; j < size; j++) total += matrix[i][j]; sums[myid] = total; Barrier(); if (myid == 0) { total = 0; for (i = 0; i < numWorkers; i++) total += sums[i]; printf("the total is %d\n", total); } }