1. with Ada.Numerics.Discrete_Random; use Ada.Numerics; 
  2. with Ada.Text_IO;                  use Ada.Text_IO; 
  3.  
  4. procedure Token_Ring is 
  5.  
  6.    No_of_Nodes       : constant Positive := 8; 
  7.    Elements_per_Node : constant Positive := 100_000; 
  8.  
  9.    type Element is new Long_Integer; 
  10.  
  11.    Size : constant Positive := Elements_per_Node * No_of_Nodes; 
  12.    subtype Index is Positive range 1 .. Size; 
  13.  
  14.    package Random_Elements is new Discrete_Random (Element); 
  15.    use Random_Elements; 
  16.  
  17.    type Nodes is mod No_of_Nodes; 
  18.  
  19.    task type Node is 
  20.       entry Handover_Id (Assigned_Id : Nodes); 
  21.       entry Token; 
  22.    end Node; 
  23.  
  24.    Ring : array (Nodes) of Node; 
  25.  
  26.    Random_Field : array (Index) of Element := (others => Element'Invalid_Value); 
  27.    Global_Max   : Element                  := Element'First; 
  28.  
  29.    Element_Generator : Generator; 
  30.  
  31.    function Partition_First (Id : Nodes) return Index is (Index'First +  Natural (Id)      * Elements_per_Node); 
  32.    function Partition_Last  (Id : Nodes) return Index is (Index'First + (Natural (Id) + 1) * Elements_per_Node - 1); 
  33.  
  34.    task body Node is 
  35.  
  36.       Id : Nodes := Nodes'Invalid_Value; 
  37.  
  38.    begin 
  39.       accept Handover_Id (Assigned_Id : Nodes) do 
  40.          Id := Assigned_Id; 
  41.       end Handover_Id; 
  42.  
  43.       declare 
  44.          Next      : constant Nodes   := Id + 1; 
  45.          Local_Max :          Element := Element'First; 
  46.  
  47.          subtype Partition is Index range Partition_First (Id) .. Partition_Last (Id); 
  48.  
  49.       begin 
  50.          accept Token; 
  51.  
  52.          if Id /= Nodes'Last then 
  53.             Ring (Next).Token; 
  54.          end if; 
  55.  
  56.          if Id = Nodes'Last then 
  57.             Ring (Next).Token; 
  58.          end if; 
  59.  
  60.          accept Token; 
  61.  
  62.          if Id /= Nodes'Last then 
  63.             Ring (Next).Token; 
  64.          end if; 
  65.       end; 
  66.    end Node; 
  67.  
  68. begin 
  69.    Reset (Element_Generator); 
  70.    for e of Random_Field loop 
  71.       e := Random (Element_Generator); 
  72.    end loop; 
  73.  
  74.    for n in Nodes loop 
  75.       Ring (n).Handover_Id (n); 
  76.    end loop; 
  77.  
  78.    Ring (Ring'First).Token; 
  79. end Token_Ring; 
  80.  
  81. --           for e of Random_Field (Partition) loop 
  82. --              Local_Max := Element'Max (Local_Max, e); 
  83. --           end loop; 
  84. -- 
  85. --           Put_Line ("Task" & Nodes'Image (Id) & " reports a local maximum of:" & Element'Image (Local_Max)); 
  86.  
  87. --           Global_Max := Element'Max (Global_Max, Local_Max); 
  88. -- 
  89. --           Put_Line ("Task" & Nodes'Image (Id) & " set a global maximum of:" & Element'Image (Global_Max));