#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include "sem.h"

struct param {
    int index;
};

#define N 1000
static double a[N][N];
static double sum = 0;
static SEM* mutex;

// Array mit Beispielwerte befüllen
static void initialize_array(void) {
    srand(0);
    for (size_t i = 0; i < N; i++) {
        for (size_t j = 0; j < N; j++) {
            a[i][j] = ((double) rand()) / RAND_MAX;
        }
    }
    // Make clean number (ignore this)
    a[0][0] -= 6.610053;
}

static void *sumRow(void *arg) {
    struct param *par = arg;
    double localSum = 0;
    
    for(int j = 0; j < N; j++) {
        localSum += a[par->index][j];
    }

    down(mutex);
    // Kritischer Abschnitt
    sum += localSum;
    up(mutex);
    return NULL;
}

int main(int argc, char *argv[]) {
    initialize_array();

    mutex = semCreate(1);
    if(mutex == NULL) {
        // TODO: Fehlerbehandlung
    }

    pthread_t tids[N];
    struct param args[N];

    // N viele Threads erstellen
    for(int i = 0; i < N; i++) {
        args[i].index = i;
        // TODO: Fehlerbehandlung
        pthread_create(&tids[i], NULL, sumRow, &args[i]);
    }

    // Auf die Beendigung aller Threads warten
    for(int i = 0; i < N; i++) {
        // TODO: Fehlerbehandlung
        pthread_join(tids[i], NULL);
    }

    semDestroy(mutex);

    printf("%f\n", sum);

    exit(EXIT_SUCCESS);
}

