// UFRGS - INF151 - Marcelo Johann - 06/05/2003 - Race Conditions

#include <stdio.h>
#include <pthread.h>
#define FALSE 0
#define TRUE 1

#define SIZE 128
int Story[SIZE];
int next = 0;
pthread_attr_t at;

typedef struct {
  char *name;
  int me;
  int other;
  } ProcID;

int want[2] = {FALSE,FALSE};
int turn = 0;
ProcID p1 = {"Isaac",0,1};
ProcID p2 = {"Jacob",1,0};

void *impressor(void*nome);
void wait (void);

int main(int argc, char**argv)
  {
  unsigned int i,a,b;
  pthread_t    t1;
  pthread_t    t2;
  for (i=0; i<SIZE; ++i)
    Story[i]=-1;
  fprintf(stderr,"Eu sou o primeiro processo.\n");
  pthread_attr_init(&at);
  pthread_attr_setscope(&at,PTHREAD_SCOPE_SYSTEM);
  a = pthread_create(&t1,&at,impressor,&p1); //isaac
  b = pthread_create(&t2,&at,impressor,&p2); //jacob
  fprintf(stderr,"Criei dois impressores: %d e %d.\n",a,b);
  pthread_join(t1, NULL);
  pthread_join(t2, NULL);
  fprintf(stderr,"Olha o que eles imprimiram:\n");
  for (i=0; i<SIZE; ++i)
    fprintf(stderr,"%d ",Story[i]);
  }

void *impressor(void*par)
  {
  int i=0;
  ProcID *p = (ProcID*) par;

  for (i=0; i<SIZE/2; ++i)
    {
    wait();
    // Peterson in
    want[p->me] = TRUE;
    turn = p->other;
    while ((want[p->other]==TRUE) && turn != p->me)
      ;
    // RC begin
    Story[next] = i;
    wait();
    ++next;
    // RC end
    want[p->me] = FALSE;
		}
  return (void*) 0;
  }

void wait (void)
  {
  int j,k;
    for (j=0;j<20;++j)
      {
      for (k=0;k<10000;++k)
	{
	j = j + 100;
	j = j - 100;
	}
      }
  }

