#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <pthread.h>
#include "myfutex.h"

int lock_val = 0;

void lock() {
  int c;
  while ((c = __sync_fetch_and_add(&lock_val, 1)) != 0) {
    sleep(1);
    printf("lock_val: %d.\n", c);
    futex_wait(&lock_val, c+1); 
  }
}

void unlock() {
  lock_val = 0;
  futex_wake(&lock_val, 1);
}

void* f_thread0(void *v) {
  lock();
  printf("Thread 0.\n");
  sleep(100);
  unlock();
  return NULL;
}

void* f_thread1(void *v) {
  lock();
  printf("Thread 1.\n");
  sleep(1);
  unlock();
  return NULL;
}

void* f_thread2(void *v) {
  lock();
  printf("Thread 2.\n");
  sleep(1);
  unlock();
  return NULL;
}

int main() {
  pthread_t thr0, thr1, thr2; 

  pthread_create(&thr0, NULL, f_thread0, NULL);
  sleep(1);
  pthread_create(&thr1, NULL, f_thread1, NULL);   
  pthread_create(&thr2, NULL, f_thread2, NULL);   
  
  pthread_exit(0);
}