home *** CD-ROM | disk | FTP | other *** search
/ Chip 1995 March / CHIP3.mdf / programm / prog4 / philos.ada < prev    next >
Encoding:
Text File  |  1991-07-01  |  3.7 KB  |  129 lines

  1.                                     -- Chapter 31 - Program 6
  2.  
  3. package One_Man is
  4.  
  5.    type AVAILABILITY is (AVAILABLE, IN_USE);
  6.    Fork_Usage : array(1..5) of AVAILABILITY;
  7.  
  8.    type ACTIVITY is (THINKING, HAS_LEFT_FORK, HAS_BOTH_FORKS);
  9.    Philosopher_Activity : array(1..5) of ACTIVITY;
  10.  
  11.    task type EATING_OR_THINKING is
  12.       entry Start(Left_Fork, Right_Fork : INTEGER);
  13.    end EATING_OR_THINKING;
  14.  
  15. end One_Man;
  16.  
  17.  
  18.  
  19.  
  20. with Text_IO, Calendar, Random;
  21. use Text_IO;
  22. package body One_Man is
  23.  
  24.    package My_Random is new Random(FLOAT);
  25.    use My_Random;
  26.    package Int_IO is new Text_IO.Integer_IO(INTEGER);
  27.    use Int_IO;
  28.  
  29.    procedure Get_Fork(Identifier    : INTEGER;
  30.                       Left_Or_Right : INTEGER) is
  31.    begin
  32.       Fork_Usage(Identifier) := IN_USE;
  33.    end Get_Fork;
  34.  
  35.    procedure Return_Fork(Identifier : INTEGER) is
  36.    begin
  37.       Fork_Usage(Identifier) := AVAILABLE;
  38.    end Return_Fork;
  39.  
  40.    task body EATING_OR_THINKING is
  41.       Left, Right : INTEGER;
  42.       Ident : INTEGER renames Left;
  43.    begin
  44.       accept Start(Left_Fork, Right_Fork : INTEGER) do
  45.          Left := Left_Fork;
  46.          Right := Right_Fork;
  47.          Philosopher_Activity(Ident) := THINKING;
  48.       end Start;
  49.       loop
  50.          Put("Philosopher"); Put(Ident,2);
  51.          Put_Line(" is thinking.");
  52.          delay Calendar.DAY_DURATION(Random_Number);
  53.          loop
  54.             delay 0.10;
  55.             exit when Fork_Usage(Left) = AVAILABLE;
  56.          end loop;
  57.          Get_Fork(Ident,Left);
  58.          Philosopher_Activity(Ident) := HAS_LEFT_FORK;
  59.          Put("Philosopher"); Put(Ident,2);
  60.          Put_Line(" has his left fork");
  61.          delay Calendar.DAY_DURATION(Random_Number);
  62.          loop
  63.             delay 0.10;
  64.             exit when Fork_Usage(Right) = AVAILABLE;
  65.          end loop;
  66.          Get_Fork(Ident,Right);
  67.          Philosopher_Activity(Ident) := HAS_BOTH_FORKS;
  68.          Put("Philosopher"); Put(Ident,2);
  69.          Put_Line(" has his right fork and is eating");
  70.          delay Calendar.DAY_DURATION(Random_Number);
  71.          Return_Fork(Left);
  72.          Return_Fork(Right);
  73.          Philosopher_Activity(Ident) := THINKING;
  74.       end loop;
  75.    end EATING_OR_THINKING;
  76.  
  77. begin
  78.  
  79.    Set_Seed;           -- Initialize the random number generator
  80.  
  81.    for Index in 1.. 5 loop
  82.       Fork_Usage(Index) := AVAILABLE;
  83.       Philosopher_Activity(Index) := THINKING;
  84.    end loop;
  85.  
  86. end One_Man;
  87.  
  88.  
  89.  
  90.  
  91. with Text_IO, One_Man;
  92. use Text_IO, One_Man;
  93.  
  94. procedure Philos is
  95.  
  96.                              -- Declare all 5 tasks
  97.    Philosopher_1 : One_Man.EATING_OR_THINKING;
  98.    Philosopher_2 : One_Man.EATING_OR_THINKING;
  99.    Philosopher_3 : One_Man.EATING_OR_THINKING;
  100.    Philosopher_4 : One_Man.EATING_OR_THINKING;
  101.    Philosopher_5 : One_Man.EATING_OR_THINKING;
  102.  
  103. begin
  104.  
  105.                              -- Assign forks to Philosophers & start
  106.    Philosopher_1.Start(Left_Fork => 1, Right_Fork => 2);
  107.    Philosopher_2.Start(Left_Fork => 2, Right_Fork => 3);
  108.    Philosopher_3.Start(Left_Fork => 3, Right_Fork => 4);
  109.    Philosopher_4.Start(Left_Fork => 4, Right_Fork => 5);
  110.    Philosopher_5.Start(Left_Fork => 5, Right_Fork => 1);
  111.  
  112.    loop                      -- Watch for deadlock to occur
  113.       delay 0.01;
  114.       if Philosopher_Activity(1) = HAS_LEFT_FORK and
  115.          Philosopher_Activity(2) = HAS_LEFT_FORK and
  116.          Philosopher_Activity(3) = HAS_LEFT_FORK and
  117.          Philosopher_Activity(4) = HAS_LEFT_FORK and
  118.          Philosopher_Activity(5) = HAS_LEFT_FORK then exit;
  119.       end if;
  120.    end loop;
  121.  
  122.    Put_Line("Deadlock detected, program operation aborted.");
  123.  
  124.    abort Philosopher_1, Philosopher_2, Philosopher_3,
  125.          Philosopher_4, Philosopher_5;
  126.  
  127. end Philos;
  128.  
  129.