1. -- 
  2. -- Uwe R. Zimmer, Australia, 2014 
  3. -- 
  4.  
  5. package body Queues is 
  6.  
  7.    protected body Protected_Queue is 
  8.  
  9.       entry Enqueue_For_All (Item : Element) when not Is_Full is 
  10.  
  11.       begin 
  12.          Queue.Elements (Queue.Free) := (Elem => Item, Reads => None_Read); 
  13.          Queue.Free := Queue.Free + 1; 
  14.       end Enqueue_For_All; 
  15.  
  16.       entry Dequeue_For_All (Item : out Element) 
  17.         when not Is_Empty 
  18.         and then (Enqueue_For_All'Count = 0 or else Is_Full) is 
  19.  
  20.       begin 
  21.          Item := Queue.Elements (Queue.Top).Elem; 
  22.          Queue.Elements (Queue.Top).Reads := All_Read; 
  23.          for Q in Queue_Enum loop 
  24.             if Queue.Readers (Q) = Queue.Top then 
  25.                Queue.Readers (Q) := Queue.Readers (Q) + 1; 
  26.             end if; 
  27.          end loop; 
  28.          Queue.Top := Queue.Top + 1; 
  29.       end Dequeue_For_All; 
  30.  
  31.       entry Dequeue (for Q in Queue_Enum) (Item : out Element) 
  32.       when not Is_Empty (Q) 
  33.         and then (Q = Queue_Enum'Last 
  34.                   or else (for all Higher in Queue_Enum'Succ (Q) .. Queue_Enum'Last 
  35.                             => Dequeue (Higher)'Count = 0 or else Is_Empty (Higher))) 
  36.         and then (Enqueue_For_All'Count = 0 or else Is_Full) 
  37.         and then (Dequeue_For_All'Count = 0) is 
  38.  
  39.       begin 
  40.          Item := Queue.Elements (Queue.Readers (Q)).Elem; 
  41.          Queue.Elements (Queue.Readers (Q)).Reads (Q) := True; 
  42.          Queue.Readers (Q) := Queue.Readers (Q) + 1; 
  43.          if Queue.Elements (Queue.Readers (Q)).Reads = All_Read then 
  44.             Queue.Top := Queue.Top + 1; 
  45.          end if; 
  46.       end Dequeue; 
  47.  
  48.       function Is_Empty return Boolean is 
  49.          (for all Q in Queue_Enum => Is_Empty (Q)); 
  50.  
  51.       function Is_Empty (Q : Queue_Enum) return Boolean is 
  52.         (Queue.Elements (Queue.Readers (Q)).Reads (Q)); 
  53.  
  54.       function Is_Full return Boolean is 
  55.         (Queue.Elements (Queue.Free).Reads /= All_Read); 
  56.  
  57.       function Length return Natural is 
  58.          (if Is_Full then Natural (Index'Last) + 1 else Natural (Queue.Free - Queue.Top)); 
  59.  
  60.       function Length (Q : Queue_Enum) return Natural is 
  61.          (if Is_Full then Natural (Index'Last) + 1 else Natural (Queue.Free - Queue.Readers (Q))); 
  62.  
  63.       function Lookahead (Depth : Index) return Element is 
  64.         (Queue.Elements (Queue.Top + Depth).Elem); 
  65.  
  66.       function Lookahead (Q : Queue_Enum; Depth : Index) return Element is 
  67.         (Queue.Elements (Queue.Readers (Q) + Depth).Elem); 
  68.  
  69.    end Protected_Queue; 
  70. end Queues;