Dinning Philosophers

Program DinningPhilosophers
 
   Const N = 5;
    Type TESTADOS = (THINKING, EATING, HUNGRY);
    Var Estados : array [ 0..N-1 ] of TESTADOS;
    Mutex : Semáforo;
    S : array [ 0..N-1 ] of Semáforo;

        Funtion Left( i: integer ) : integer;
        BEGIN
            Left := (i-1) mod N;
        END;

        Funtion Right ( i: integer ) : integer;
        BEGIN
            Right := (i+1) mod N;
        END;

        Procedure Test( i: integer );
        BEGIN
            if Estados[i] = HUNGRY AND Estados[Left(i)] <> EATING AND Estados[Right(i)] <> EATING then
                BEGIN
                    Estados[i] = EATING; /* Estado Filósofo indicando que vai comer */
  
                 Up(S[i]);
                END;
        END;

        Procedure pegaGarfos( i: integer );
        BEGIN
            Down(Mutex);
            Estados[i] = HUNGRY; /* Estado Filósofo indicando que está HUNGRY */
            Test(i);
            Up(Mutex);
  
         Down(S[i]);
        END;

        Procedure liberaGarfos( i: integer );
        BEGIN
  
         Down(Mutex);
            Estados[i] = THINKING; /* Estado Filósofo muda para THINKING */
              
Test( Left(i) );
               Test( Right(i) );
               Up(Mutex);
        END;

        Procedure Philosopher( i: integer );
        BEGIN
            Repeat
                Think; /* Filósofo pensa */
      
          pegaGarfos( i ); /* Obtém garfos */
                E
at; /* Filósofo come */
                liberaGarfos( i ); /* Libera garfos */
               
Until false;
        END;

 BEGIN
        Mutex.valor := 1;
        PARBEGIN
               Philosopher(0);
               Philosopher(1);
               Philosopher(2);
               Philosopher(3);
               Philosopher(4);
        PAREND;

END.