1. -- 
  2. -- Uwe R. Zimmer, Australia, 2013 
  3. -- 
  4.  
  5. package body Queue_Pack_Task_Generic is 
  6.  
  7.    task body Queue_Task is 
  8.  
  9.       subtype Marker is Natural range 0 .. Queue_Size - 1; 
  10.       -- bounds chosen such that modulo arithmetic can be used 
  11.       type List is array (Marker) of Element; 
  12.       type Queue_Type is record 
  13.          Top, Free : Marker  := Marker'First; 
  14.          Is_Empty  : Boolean := True; 
  15.          Elements  : List; 
  16.       end record; 
  17.  
  18.       Queue : Queue_Type; 
  19.  
  20.       function Is_Empty return Boolean is 
  21.         (Queue.Is_Empty); 
  22.  
  23.       function Is_Full return Boolean is 
  24.         (not Queue.Is_Empty and then Queue.Top = Queue.Free); 
  25.  
  26.    begin 
  27.       loop 
  28.          select 
  29.             when not Is_Full => 
  30.                accept Enqueue (Item :     Element) do 
  31.                   Queue.Elements (Queue.Free) := Item; 
  32.                end Enqueue; 
  33.                Queue.Free     := (Queue.Free + 1) mod Queue_Size; 
  34.                Queue.Is_Empty := False; 
  35.          or 
  36.             when not Is_Empty => 
  37.                accept Dequeue (Item : out Element) do 
  38.                   Item := Queue.Elements (Queue.Top); 
  39.                end Dequeue; 
  40.                Queue.Top      := (Queue.Top + 1) mod Queue_Size; 
  41.                Queue.Is_Empty := Queue.Top = Queue.Free; 
  42.          or 
  43.             accept Is_Empty (Result : out Boolean) do 
  44.                Result := Is_Empty; 
  45.             end Is_Empty; 
  46.          or 
  47.             accept Is_Full  (Result : out Boolean) do 
  48.                Result := Is_Full; 
  49.             end Is_Full; 
  50.          or 
  51.             terminate; 
  52.          end select; 
  53.       end loop; 
  54.    end Queue_Task; 
  55.  
  56. end Queue_Pack_Task_Generic;