Dining Philosophers with Host (2)
package dph is
N : constant integer := 2; -- number of philosophers
type phil_range is range 0 .. (N - 1); -- range for # of philosophers eating
task phil_1;
task phil_2;
task fork_1 is
entry up;
entry down;
end fork_1;
task fork_2 is
entry up;
entry down;
end fork_2;
task host is
entry enter;
entry leave;
end host;
end dph;
package body dph is
task body phil_1 is
done : Boolean;
begin
loop
host.enter;
-- unlike for the other dining philosophers, we don't avoid deadlock
-- by having phil_1 pick up fork_1 first here. That's because the host
-- task is supposed to avoid the deadlock
fork_2.up;
fork_1.up; --event[{phil_1_eating}]
fork_2.down; --eventb[{phil_1_not_eating}]
fork_1.down;
host.leave;
exit when done;
end loop;
end phil_1;
task body phil_2 is
done : Boolean;
begin
loop
host.enter;
fork_1.up;
fork_2.up; --event[{phil_2_eating}]
fork_1.down; --eventb[{phil_2_not_eating}]
fork_2.down;
host.leave;
exit when done;
end loop;
end phil_2;
task body fork_1 is
done : Boolean;
begin
loop
accept up;
accept down;
exit when done;
end loop;
end fork_1;
task body fork_2 is
done : Boolean;
begin
loop
accept up;
accept down;
exit when done;
end loop;
end fork_2;
task body host is
done : Boolean;
count : phil_range;
begin
count := 0; --event[{count=0}]
loop
select
when count < phil_range'Last =>
accept enter; --eventb[{countis<1}]
count := count + 1; --event[{countinc}]
null;
or
accept leave;
count := count - 1; --event[{countdec}]
null;
end select;
exit when done;
end loop;
end host;
end dph;