/***************************************************************************** * SOURCE: This is a translation of a Pthread program from the Lawrence Livermore * Computing Center POSIX Threads Programming Exercise at: * https://computing.llnl.gov/tutorials/pthreads/exercise.html * FILE: mpithreads_threads.cvl * DESCRIPTION: * This simple program illustrates the use of Pthreads in a program obtained * by modifying a serial code that performs a dot product. It is the second * of four codes used to show the progression from a serial program to a * hybrid MPI/Pthreads program. The other relevant codes are: * - mpithreads_serial.c - The serial version * - mpithreads_mpi.c - A distributed memory programming model with MPI * - mpithreads_both.c - A hybrid model that utilizes both MPI and * Pthreads to execute on systems that are comprised of clusters * of SMP's. * The main data is made available to all threads through a globally * accessible structure. Each thread works on a different part of the * data. The main thread waits for all the threads to complete their * computations, and then it prints the resulting sum. * Command line execution: * civl verify -inputMAXTHRDS=8 -inputVECLEN=100 mpithreads_thread.cvl ******************************************************************************/ #include "pthread.cvh" #include #include #include /* The following structure contains the necessary information to allow the function "dotprod" to access its input data and place its output into the structure. This structure is unchanged from the sequential version. */ typedef struct { double *a; double *b; double sum; int veclen; } DOTDATA; /* Define globally accessible variables and a mutex */ $input int MAXTHRDS; $input int VECLEN; DOTDATA dotstr; pthread_t callThd[MAXTHRDS]; pthread_mutex_t mutexsum; /* The function dotprod is activated when the thread is created. As before, all input to this routine is obtained from a structure of type DOTDATA and all output from this function is written into this structure. The benefit of this approach is apparent for the multi-threaded program: when a thread is created we pass a single argument to the activated function - typically this argument is a thread number. All the other information required by the function is accessed from the globally accessible structure. */ void *dotprod(void *arg) { /* Define and use local variables for convenience */ int i, start, end, len ; long offset; double mysum, *x, *y; offset = (long)*arg; // Dereference rather than direct conv len = dotstr.veclen; start = offset*len; end = start + len; x = dotstr.a; y = dotstr.b; /* Perform the dot product and assign result to the appropriate variable in the structure. */ mysum = 0; for (i=start; i