1. -- 
  2. -- Uwe R. Zimmer, Australia, 2014 
  3. -- 
  4.  
  5. pragma Initialize_Scalars; 
  6.  
  7. generic 
  8.  
  9.    type Element is private; 
  10.    type Index   is mod <>;  -- Modulo defines size of the queue. 
  11.  
  12.    type Queue_Enum is (<>); -- Allows for multiple readers without loosing items. 
  13.  
  14. package Queues is 
  15.  
  16.    type Queue_Type is limited private; 
  17.  
  18.    protected type Protected_Queue is 
  19.  
  20.       -------------------------------------------------------------------------- 
  21.       -- 
  22.       -- Order of processing: 
  23.       -- 
  24.       -- 1. Enqueue takes priority over Dequeue. 
  25.       -- 2. Dequeues with higher Queue_Enum values take priority over 
  26.       --    Dequeues with lower Queue_Enum values. 
  27.       -- 3. Internal progress first rule guarantees fairness 
  28.       --    (no task is served twice while another servicable task is blocked). 
  29.       -- 
  30.       -------------------------------------------------------------------------- 
  31.  
  32.       entry Enqueue_For_All (Item :     Element); 
  33.  
  34.       entry Dequeue_For_All (Item : out Element); 
  35.  
  36.       entry Dequeue (Queue_Enum) (Item : out Element); 
  37.  
  38.       function Is_Empty                       return Boolean; 
  39.       function Is_Empty  (Q     : Queue_Enum) return Boolean; 
  40.       function Is_Full                        return Boolean; 
  41.       function Length                         return Natural; 
  42.       function Length    (Q     : Queue_Enum) return Natural; 
  43.       function Lookahead (Depth : Index)      return Element; 
  44.       function Lookahead (Q     : Queue_Enum; 
  45.                           Depth : Index)      return Element; 
  46.  
  47.    private 
  48.  
  49.       Queue : Queue_Type; 
  50.  
  51.    end Protected_Queue; 
  52.  
  53. private 
  54.    type Markers is array (Queue_Enum) of Index; 
  55.  
  56.    type Readouts is array (Queue_Enum) of Boolean; 
  57.    All_Read  : constant Readouts := (others => True); 
  58.    None_Read : constant Readouts := (others => False); 
  59.  
  60.    type Element_and_Readouts is record 
  61.       Elem  : Element; -- Initialized to invalids 
  62.       Reads : Readouts := All_Read; 
  63.    end record; 
  64.    type List is array (Index) of Element_and_Readouts; 
  65.  
  66.    type Queue_Type is record 
  67.       Free, 
  68.       Top      : Index   := Index'First; 
  69.       Readers  : Markers := (others => Index'First); 
  70.       Elements : List; 
  71.    end record; 
  72.  
  73. end Queues;