-- $Id: prodcons.gnat,v 1.0 2003/06/11 12:10:00 dada Exp $
-- http://dada.perl.it/shootout/
-- Ada 95 code by C.C.

with Ada.Strings.Fixed, Ada.Command_Line, Text_IO;

procedure ProdCons is

   type Data_Type is new Integer;
   End_Of_Data    : constant Data_Type := Data_Type'First;

   protected Queue is
      entry Put (Data : Data_Type);
      entry Get (Data_Out : out Data_Type);
   private
      Count          : Natural := 0;
      Buffer         : Data_Type;
   end Queue;

   protected body Queue is
      entry Put (Data : Data_Type)
         when Count = 0 is
      begin
         Buffer := Data;
         Count := Count + 1;
      end Put;

      entry Get (Data_Out : out Data_Type)
         when Count /= 0 is
      begin
         Data_Out := Buffer;
         Count := Count - 1;
      end Get;
   end Queue;

   Produced, Consumed : Natural := 0;

   task type Producer_Task (N : Natural);
   task type Consumer_Task (N : Natural);

   task body Producer_Task is
   begin
      for Data_K in 1 .. Data_Type (N) loop
         Queue.Put (Data => Data_K);
         Produced := Produced + 1;
      end loop;
      Queue.Put (Data => End_Of_Data);
   end Producer_Task;

   task body Consumer_Task is
      Data        : Data_Type;
   begin
      loop
         Queue.Get (Data_Out => Data);
         exit when Data = End_Of_Data;
         Consumed := Consumed + 1;
      end loop;
   end Consumer_Task;

   function L_Trim (Source : String; Side : Ada.Strings.Trim_End :=
               Ada.Strings.Left) return String renames Ada.Strings.Fixed.Trim;
   N        : Natural := 0;
begin
   begin
      N := Natural'Value (Ada.Command_Line.Argument (1));
   exception
      when Constraint_Error => null;
   end;
   declare
      Producer    : Producer_Task (N => N);
      Consumer    : Consumer_Task (N => N);
   begin
      null;
   end;
   Text_IO.Put_Line (L_Trim (Natural'Image (Produced)) &
            Natural'Image (Consumed));
end ProdCons;