source: CIVL/examples/pthread/dotprod_mutex.cvl@ bf81b8c

1.23 2.0 main test-branch
Last change on this file since bf81b8c was 38374b7, checked in by John Edenhofner <johneden@…>, 12 years ago

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@984 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 4.2 KB
Line 
1/*****************************************************************************
2* FILE: dotprod_mutex.c
3* DESCRIPTION:
4* This example program illustrates the use of mutex variables
5* in a threads program. This version was obtained by modifying the
6* serial version of the program (dotprod_serial.c) which performs a
7* dot product. The main data is made available to all threads through
8* a globally accessible structure. Each thread works on a different
9* part of the data. The main thread waits for all the threads to complete
10* their computations, and then it prints the resulting sum.
11* SOURCE: Vijay Sonnad, IBM
12* LAST REVISED: 01/29/09 Blaise Barney
13******************************************************************************/
14#include "pthread.cvh"
15#include <civlc.h>
16#include <stdio.h>
17#include <stdlib.h>
18
19/*
20The following structure contains the necessary information
21to allow the function "dotprod" to access its input data and
22place its output into the structure. This structure is
23unchanged from the sequential version.
24*/
25
26typedef struct
27 {
28 double *a;
29 double *b;
30 double sum;
31 int veclen;
32 } DOTDATA;
33
34/* Define globally accessible variables and a mutex */
35
36#define NUMTHRDS 4
37#define VECLEN 100000
38 DOTDATA dotstr;
39 pthread_t callThd[NUMTHRDS];
40 pthread_mutex_t mutexsum;
41
42/*
43The function dotprod is activated when the thread is created.
44As before, all input to this routine is obtained from a structure
45of type DOTDATA and all output from this function is written into
46this structure. The benefit of this approach is apparent for the
47multi-threaded program: when a thread is created we pass a single
48argument to the activated function - typically this argument
49is a thread number. All the other information required by the
50function is accessed from the globally accessible structure.
51*/
52
53void *dotprod(void *arg)
54{
55
56/* Define and use local variables for convenience */
57
58 int i, start, end, len ;
59 long offset;
60 double mysum, *x, *y;
61 offset = (long)arg;
62
63 len = dotstr.veclen;
64 start = offset*len;
65 end = start + len;
66 x = dotstr.a;
67 y = dotstr.b;
68
69/*
70Perform the dot product and assign result
71to the appropriate variable in the structure.
72*/
73 mysum = 0;
74 for (i=start; i<end ; i++)
75 {
76 mysum += (x[i] * y[i]);
77 }
78
79/*
80Lock a mutex prior to updating the value in the shared
81structure, and unlock it upon updating.
82*/
83 pthread_mutex_lock (&mutexsum);
84 dotstr.sum += mysum;
85 printf("Thread %ld did %d to %d: mysum=%f global sum=%f\n",offset,start,end,mysum,dotstr.sum);
86 pthread_mutex_unlock (&mutexsum);
87
88 pthread_exit((void*) 0);
89}
90
91/*
92The main program creates threads which do all the work and then
93print out result upon completion. Before creating the threads,
94The input data is created. Since all threads update a shared structure, we
95need a mutex for mutual exclusion. The main thread needs to wait for
96all threads to complete, it waits for each one of the threads. We specify
97a thread attribute value that allow the main thread to join with the
98threads it creates. Note also that we free up handles when they are
99no longer needed.
100*/
101
102int main (int argc, char *argv[])
103{
104long i;
105double *a, *b;
106void *status;
107pthread_attr_t attr;
108
109/* Assign storage and initialize values */
110
111a = (double*) malloc (NUMTHRDS*VECLEN*sizeof(double));
112b = (double*) malloc (NUMTHRDS*VECLEN*sizeof(double));
113
114for (i=0; i<VECLEN*NUMTHRDS; i++) {
115 a[i]=1;
116 b[i]=a[i];
117 }
118
119dotstr.veclen = VECLEN;
120dotstr.a = a;
121dotstr.b = b;
122dotstr.sum=0;
123
124pthread_mutex_init(&mutexsum, NULL);
125
126/* Create threads to perform the dotproduct */
127pthread_attr_init(&attr);
128pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
129
130for(i=0;i<NUMTHRDS;i++)
131 {
132 /* Each thread works on a different set of data.
133 * The offset is specified by 'i'. The size of
134 * the data for each thread is indicated by VECLEN.
135 */
136 pthread_create(&callThd[i], &attr, dotprod, (void *)i);
137 }
138
139pthread_attr_destroy(&attr);
140/* Wait on the other threads */
141
142for(i=0;i<NUMTHRDS;i++) {
143 pthread_join(callThd[i], &status);
144 }
145/* After joining, print out the results and cleanup */
146
147printf ("Sum = %f \n", dotstr.sum);
148free (a);
149free (b);
150pthread_mutex_destroy(&mutexsum);
151pthread_exit(NULL);
152}
Note: See TracBrowser for help on using the repository browser.