/*
 * Algoritmo de Dekker.
 */
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

volatile int s = 0; /* Variável compartilhada */
volatile int vez = 0; /* Indica de qual thread tem prioridade
                         entrar na região crítica */
volatile int interesse[2] = {0, 0}; /* Indica quais threads estão
                                       interessadas em entrar na região crítica */

void* f_thread_0(void *v) {
  int i;

  for (i = 0; i < 10; i++) {
    interesse[0] = 1; /* Marca que esta thread está interessada */
    sleep(1);
    while (interesse[1]) /* Enquanto a outra thread puder estar na região crítica */  
      if (vez != 0) {  
	while (vez != 0);  /* Aguarda ser a vez desta thread */ 
      }
  
    s = 0;
    printf("Thread 0, s = %d.\n", s); 
  
    vez = 1;           /* Passa a vez para a outra thread */
    interesse[0] = 0;  /* Marca que saiu da região crítica */
    sleep(1);
  }
  return NULL;
}

void* f_thread_1(void *v) {
  int i;

  for (i = 0; i < 10; i++) {
    interesse[1] = 1; /* Marca que esta thread está interessada */
    while (interesse[0]) 
      if (vez != 1) {
	while (vez != 1);
        sleep(1);
      }
  
    s = 1;
    printf("Thread 1, s = %d.\n", s); 
  
    vez = 0;           /* Passa a vez para a outra thread */
    interesse[1] = 0;  /* Marca que saiu da região crítica */
  }
  return NULL;
}

int main() {

  pthread_t thr0, thr1;

  pthread_create(&thr0, NULL, f_thread_0, NULL);
  pthread_create(&thr1, NULL, f_thread_1, NULL);

  pthread_join(thr0, NULL); 
  pthread_join(thr1, NULL); 
  return 0;
}