#include <pthread.h>
#include <stdio.h>
#include <time.h>
 
// use 4 for a quad processor, but try also with 1 and 2 threads
// to check the running time and the system load
#define thread_count 4
 
// matrix dimension
#define dim 1500
 
struct param {
  int start_line, end_line;
};
 
int a[dim][dim], b[dim][dim], c[dim][dim];
 
void init_matrix(int m[dim][dim]) {
   int i, j;
   for (i = 0; i < dim; i++)
     for (j = 0; j < dim; j++)
       m[i][j] = random() % 100;
}
 
void* thread_function(void *v) {
  struct param *p = (struct param *) v;
  
  int i, j, k;
  for (i = p->start_line; i < p->end_line; i++)
    for (j = 0; j < dim; j++) {
      int s = 0;
      for (k = 0; k < dim; k++)
        s += a[i][k] * b[k][j];
      c[i][j] = s;
    }
}
 
int main() {
  int i;
  struct param params[thread_count];
  pthread_t t[thread_count];
  
  srand(getpid());
  int start_time, end_time;
  
  init_matrix(a);
  init_matrix(b);
  
  start_time = time(NULL);
 
  for (i = 0; i < thread_count; i++) {
    int code;
    params[i].start_line = i * (dim / thread_count);
    params[i].end_line = (i + 1) * (dim / thread_count);
    
    code = pthread_create(&t[i], NULL, thread_function, ¶ms[i]);
    if (code != 0)
      printf("Error starting thread %d\n", i);
  }
  
  for (i = 0; i < thread_count; i++) 
    pthread_join(t[i], NULL);
  
  end_time = time(NULL);
  
  printf("Running time: %d\n", end_time - start_time);
}