Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <math.h>
- #include "matmul.h"
- #include <pthread.h>
- #include <semaphore.h>
- #include <unistd.h>
- #include <fcntl.h>
- sem_t *availableWork;
- int rowsDone, _n, currentRow, _itt;
- double *_t, *_t1, *_error;
- pthread_mutex_t doingWork, mut_RowsDone, mut_CurrentRow;
- void compute(double *error, int n, double *t, double *t1, int itt_max)
- {
- int i, j, itt;
- double errori, sum;
- double *ttemp;
- pthread_t threads[N];
- _n = n;
- _t = t;
- _t1 = t1;
- _error = error;
- // initialize mutex
- if(pthread_mutex_init(&doingWork, NULL) != 0) perror("mutex");
- if(pthread_mutex_init(&mut_RowsDone, NULL) != 0) perror("mutex");
- if(pthread_mutex_init(&mut_CurrentRow, NULL) != 0) perror("mutex");
- // initialize semaphore
- availableWork = sem_open("sem", O_CREAT, 0644, 0);
- // initialize threads.
- for (i = 0; i < NUMTHREADS; ++i) {
- pthread_create(&threads[i], NULL, &doWork, (void *)i);
- }
- // print success to the console
- fprintf(stderr, "Threads initialized.\n\n");
- // while we're less than or equal to the number of iterations
- for(itt=0; itt<=itt_max; itt++)
- {
- // lock the mutex so the process doesn't end prematurely
- pthread_mutex_lock(&doingWork);
- _itt = itt;
- // post work to the semaphore
- for (i = 0; i < n; ++i) {
- sem_post(availableWork);
- }
- // if there is no more work currently in the queue, the last thread to do work will unlock this
- // and allow continued execution
- pthread_mutex_lock(&doingWork);
- // answer into temporary array
- ttemp = t1;
- // old x vector into t1 (why?)
- t1 = t;
- // new x vector is the answer from the last multiplication
- t = ttemp;
- // print, do it all over again
- //printf("%5d %14.6e\n", itt, error[itt]);
- }
- }
- void *doWork(void *arg)
- {
- double sum, errori;
- int j, doingWorkOnRow;
- while(1)
- {
- sem_wait(availableWork);
- doingWorkOnRow = getCurrentRow();
- // columns of the rows
- for(j=0; j< _n; j++)
- {
- // multiply an entry
- sum += a[doingWorkOnRow][j] * _t[j];
- }
- _t1[doingWorkOnRow] = sum + b[doingWorkOnRow];
- errori = fabs(_t1[doingWorkOnRow] - _t[doingWorkOnRow]);
- if(errori > _error[_itt])
- {
- _error[_itt] = errori;
- }
- fprintf(stderr, "Thread %d did work. ThreadsDoingWork = %d\n", (int)arg, rowsDone);
- incRowsDone();
- // if all the rows in this iteration are done, allow the main thread to continue
- if(rowsDone == _n - 1) pthread_mutex_unlock(&doingWork);
- }
- }
- int incRowsDone()
- {
- if(pthread_mutex_lock(&mut_RowsDone) != 0) perror("mutex lock");
- rowsDone = rowsDone + 1;
- pthread_mutex_unlock(&mut_RowsDone);
- return rowsDone;
- }
- int getCurrentRow()
- {
- if(pthread_mutex_lock(&mut_CurrentRow)!= 0) perror("mutex lock");
- currentRow++;
- pthread_mutex_unlock(&mut_CurrentRow);
- return currentRow - 1;
- }
Add Comment
Please, Sign In to add comment