#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>


#define NUM_THREADS      4
#define MAX_COUNT 10000000

struct tdata {
    int tid;
};

int counter = 0;
/* POSIX Thread mutex */
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
/* Don't confuse it with POSIX Semaphore */

/* In cases where default mutex attributes are appropriate, */
/* the macro PTHREAD_MUTEX_INITIALIZER can be used to initialize mutexes that are */
/* statically allocated. The effect shall be equivalent to dynamic initialization */
/* by a call to pthread_mutex_init() with parameter attr specified as NULL, */
/* except that no error checks are performed. */

void *count(void *ptr) {
  long i, max = MAX_COUNT/NUM_THREADS;
  int tid = ((struct tdata *) ptr)->tid;

  for (i=0; i < max; i++) {
    pthread_mutex_lock(&mutex);
    counter += 1;
    pthread_mutex_unlock(&mutex);
  }
    printf("End %d counter: %d\n", tid, counter);
    return NULL;
}

int main (int argc, char *argv[]) {
    pthread_t threads[NUM_THREADS];
    int rc, i;
    struct tdata id[NUM_THREADS];

    for(i=0; i<NUM_THREADS; i++){
        id[i].tid = i;
        rc = pthread_create(&threads[i], NULL, count, (void *) &id[i]);
    }

    for(i=0; i<NUM_THREADS; i++){
        pthread_join(threads[i], NULL);
    }

    printf("Counter value: %d Expected: %d\n", counter, MAX_COUNT);
    return 0;
}
