163 lines
5.3 KiB
Plaintext
163 lines
5.3 KiB
Plaintext
COMMENT
|
|
! DEADLOCK IS PREVENTED BY REVERSING THE ORDER OF TAKING THE CHOPSTICKS FOR THE LAST PHILOSOPHER.
|
|
! THAT MEANS ALL PHILOSOPHERS FIRST TAKE THE LEFT CHOPSTICK, THEN THE RIGHT CHOPSTICK.
|
|
! BUT THE LAST PHILOSOPHER FIRST TAKES THE RIGHT CHOPSTICK, THEN THE LEFT.
|
|
!
|
|
! THE DETACH STATEMENT IN CLASS PHILOSOPHER GIVES CONTROL BACK TO THE MAIN BLOCK.
|
|
! THE MAIN BLOCK CALLS/RESUMES ALL THE PHILOSOPHERS USING THE RESUME(PHILOSOPHER) STATEMENT.
|
|
! THIS CONTINUES THE CODE IN THE PHILOSOPHER CLASS AFTER THE LAST DETACH STATEMENT.
|
|
! (ANOTHER NAME FOR THIS FEATURE IS THE CONCEPT OF A COROUTINE)
|
|
;
|
|
BEGIN
|
|
INTEGER N;
|
|
INTEGER PNR, CNR;
|
|
INTEGER SEED;
|
|
SEED := ININT;
|
|
N := 5;
|
|
BEGIN
|
|
|
|
CLASS CHOPSTICK;
|
|
BEGIN
|
|
REF(PHILOSOPHER) OWNER;
|
|
INTEGER ID;
|
|
ID := CNR := CNR + 1;
|
|
END CHOPSTICK;
|
|
|
|
CLASS PHILOSOPHER(L,R);
|
|
REF(CHOPSTICK) L,R;
|
|
BEGIN
|
|
INTEGER ID;
|
|
ID := PNR := PNR + 1;
|
|
WHILE TRUE DO
|
|
BEGIN
|
|
DETACH;
|
|
|
|
OUTTEXT("PHILOSOPHER(");
|
|
OUTINT(ID, 0);
|
|
OUTTEXT(") THINKING...");
|
|
OUTIMAGE;
|
|
DETACH;
|
|
|
|
WHILE RANDINT(0,1,SEED) = 0 DO BEGIN
|
|
OUTTEXT("PHILOSOPHER(");
|
|
OUTINT(ID, 0);
|
|
OUTTEXT(") THINKING DEEPER...");
|
|
OUTIMAGE;
|
|
DETACH;
|
|
END;
|
|
|
|
WHILE L.OWNER =/= NONE DO BEGIN
|
|
OUTTEXT("PHILOSOPHER(");
|
|
OUTINT(ID, 0);
|
|
OUTTEXT(") WAITING FOR LEFT CHOPSTICK(");
|
|
OUTINT(L.ID, 0);
|
|
OUTTEXT(") ...");
|
|
OUTIMAGE;
|
|
DETACH;
|
|
END;
|
|
L.OWNER :- THIS PHILOSOPHER;
|
|
OUTTEXT("PHILOSOPHER(");
|
|
OUTINT(ID, 0);
|
|
OUTTEXT(") GRABBED LEFT CHOPSTICK(");
|
|
OUTINT(L.ID, 0);
|
|
OUTTEXT(")");
|
|
OUTIMAGE;
|
|
|
|
WHILE R.OWNER =/= NONE DO BEGIN
|
|
OUTTEXT("PHILOSOPHER(");
|
|
OUTINT(ID, 0);
|
|
OUTTEXT(") WAITING FOR RIGHT CHOPSTICK(");
|
|
OUTINT(R.ID, 0);
|
|
OUTTEXT(") ...");
|
|
OUTIMAGE;
|
|
DETACH;
|
|
END;
|
|
R.OWNER :- THIS PHILOSOPHER;
|
|
OUTTEXT("PHILOSOPHER(");
|
|
OUTINT(ID, 0);
|
|
OUTTEXT(") GRABBED RIGHT CHOPSTICK(");
|
|
OUTINT(R.ID, 0);
|
|
OUTTEXT(")");
|
|
OUTIMAGE;
|
|
|
|
OUTTEXT("PHILOSOPHER(");
|
|
OUTINT(ID, 0);
|
|
OUTTEXT(") EATING...");
|
|
OUTIMAGE;
|
|
WHILE RANDINT(0,1,SEED) = 0 DO BEGIN
|
|
DETACH;
|
|
OUTTEXT("PHILOSOPHER(");
|
|
OUTINT(ID, 0);
|
|
OUTTEXT(") STILL EATING...");
|
|
OUTIMAGE;
|
|
END;
|
|
L.OWNER :- NONE;
|
|
R.OWNER :- NONE;
|
|
OUTTEXT("PHILOSOPHER(");
|
|
OUTINT(ID, 0);
|
|
OUTTEXT(") RELEASED LEFT CHOPSTICK(");
|
|
OUTINT(L.ID, 0);
|
|
OUTTEXT(")");
|
|
OUTIMAGE;
|
|
OUTTEXT("PHILOSOPHER(");
|
|
OUTINT(ID, 0);
|
|
OUTTEXT(") RELEASED RIGHT CHOPSTICK(");
|
|
OUTINT(R.ID, 0);
|
|
OUTTEXT(")");
|
|
OUTIMAGE;
|
|
END;
|
|
END PHILOSOPHER;
|
|
|
|
!---------------------------------------|
|
|
! |
|
|
! |
|
|
! (3) |
|
|
! P2 P3 |
|
|
! |
|
|
! (2) (4) |
|
|
! |
|
|
! |
|
|
! P1 P4 |
|
|
! |
|
|
! |
|
|
! (1) (5) |
|
|
! |
|
|
! P5 | only P5 takes Right first (5), then Left (1)
|
|
! |
|
|
!---------------------------------------|
|
|
!;
|
|
|
|
REF(PHILOSOPHER) ARRAY PHILS (1:N);
|
|
REF(CHOPSTICK) L, R;
|
|
INTEGER I, LOOPS;
|
|
|
|
R :- NEW CHOPSTICK;
|
|
FOR I := 1 STEP 1 UNTIL N-1 DO
|
|
BEGIN
|
|
L :- NEW CHOPSTICK;
|
|
PHILS(I) :- NEW PHILOSOPHER(L,R);
|
|
R :- L;
|
|
END;
|
|
! REVERSED ORDER FOR THE LAST PHILOSOPHER ;
|
|
PHILS(N) :- NEW PHILOSOPHER(R,PHILS(1).R);
|
|
|
|
FOR I := 1 STEP 1 UNTIL N DO BEGIN
|
|
OUTTEXT("PHILOSOPHER(ID=");
|
|
OUTINT(PHILS(I).ID, 0);
|
|
OUTTEXT(", L=");
|
|
OUTINT(PHILS(I).L.ID, 0);
|
|
OUTTEXT(", R=");
|
|
OUTINT(PHILS(I).R.ID, 0);
|
|
OUTTEXT(")");
|
|
OUTIMAGE;
|
|
END;
|
|
|
|
FOR LOOPS := 1 STEP 1 UNTIL 10 DO BEGIN
|
|
FOR I := 1 STEP 1 UNTIL N DO BEGIN
|
|
RESUME(PHILS(I));
|
|
END;
|
|
END;
|
|
|
|
END;
|
|
END.
|