Famous Edsger Dijkstra competing for access problem.
Code: Select all
PROCEDURE Left (i: INTEGER): INTEGER;
BEGIN RETURN (i+N-1) MOD N END Left;
PROCEDURE Right (i: INTEGER): INTEGER;
BEGIN RETURN (i+1) MOD N END Right;
PROCEDURE Print;
VAR j: INTEGER;
BEGIN
FOR j := 0 TO N-1 DO
CASE philosopher[j].state OF
| THINKING: Log.String("THINKING");
| HUNGRY: Log.String("HUNGRY");
| EATING: Log.String("EATING");
END;
IF j < N-1 THEN Log.Char('.') END
END;
Log.Ln
END Print;
PROCEDURE Test (i: INTEGER);
BEGIN
IF (philosopher[i].state = HUNGRY) & (philosopher[Left(i)].state # EATING)
& (philosopher[Right(i)].state # EATING) THEN
philosopher[i].state := EATING;
Print;
Co.SemUp(philosopher[i].sem)
END
END Test;
PROCEDURE TakeForks (i: INTEGER);
BEGIN
philosopher[i].state := HUNGRY;
Print;
Test(i);
Co.SemDown(philosopher[i].sem);
END TakeForks;
PROCEDURE PutForks (i: INTEGER);
BEGIN
philosopher[i].state := THINKING;
Print;
Test(Left(i));
Test(Right(i));
END PutForks;
PROCEDURE Do (t: Ct.Task) ;
VAR ph: Philosopher;
BEGIN
ph := t(Philosopher);
WHILE ~ph.eor DO
Co.Sleep(ph.t_thinking);
TakeForks(ph.i);
Co.Sleep(ph.t_eating);
PutForks(ph.i);
END
END Do;
Console listing is as following:
THINKING.THINKING.THINKING.THINKING.HUNGRY
THINKING.THINKING.THINKING.THINKING.EATING
THINKING.THINKING.THINKING.HUNGRY.EATING
THINKING.THINKING.HUNGRY.HUNGRY.EATING
THINKING.THINKING.EATING.HUNGRY.EATING
THINKING.HUNGRY.EATING.HUNGRY.EATING
HUNGRY.HUNGRY.EATING.HUNGRY.EATING
HUNGRY.HUNGRY.EATING.HUNGRY.THINKING
EATING.HUNGRY.EATING.HUNGRY.THINKING
EATING.HUNGRY.THINKING.HUNGRY.THINKING
EATING.HUNGRY.THINKING.EATING.THINKING