Annotated Ada Reference ManualLegal Information
Contents   Index   References   Search   Previous   Next 

9.11 Example of Tasking and Synchronization

Examples

1
The following example defines a buffer protected object to smooth variations between the speed of output of a producing task and the speed of input of some consuming task. For instance, the producing task might have the following structure:
2
task Producer;
3/2
{AI95-00433-01} task body Producer is
   Person : Person_Name; -- see 3.10.1 Char : Character;
begin
   loop
      ... --  simulate arrival of the next customer produce the next character Char
      Buffer.Append_Wait(Person) Write(Char);
      exit when Person = null Char = ASCII.EOT;
   end loop;
end Producer;
4
and the consuming task might have the following structure:
5
task Consumer;
6/2
{AI95-00433-01} task body Consumer is
   Person : Person_Name; Char : Character;
begin
   loop
      Buffer.Remove_First_Wait(Person) Read(Char);
      exit when Person = null Char = ASCII.EOT;
      ... --  simulate serving a customer consume the character Char
   end loop;
end Consumer;
7/2
{AI95-00433-01} The buffer object contains an internal array pool of person names characters managed in a round-robin fashion. The array pool has two indices, an In_Index denoting the index space for the next input person name character and an Out_Index denoting the index space for the next output person name character.
7.1/2
  {AI95-00433-01} The Buffer is defined as an extension of the Synchronized_Queue interface (see 3.9.4), and as such promises to implement the abstraction defined by that interface. By doing so, the Buffer can be passed to the Transfer class-wide operation defined for objects of a type covered by Queue'Class.
8/2
{AI95-00433-01} protected Buffer is new Synchronized_Queue with  -- see 3.9.4
   entry Append_Wait(Person : in Person_Name); Read (C : out Character);
   entry Remove_First_Wait(Person : out Person_Name);
   function Cur_Count return Natural;
   function Max_Count return Natural;
   procedure Append(Person : in Person_Name);
   procedure Remove_First(Person : out Person_Name);
 Write(C : in  Character);
private
   Pool      : Person_Name_Array String(1 .. 100);
   Count     : Natural := 0;
   In_Index, Out_Index : Positive := 1;
end Buffer;
9/2
{AI95-00433-01} protected body Buffer is
   entry Append_Wait(Person : in Person_Name) Write(C : in Character)
      when Count < Pool'Length is
   begin
      Append(Person); Pool(In_Index) := C;
      In_Index := (In_Index mod Pool'Length) + 1;
      Count    := Count + 1;

   end Append_Wait Write;
9.1/2
{AI95-00433-01}    procedure Append(Person : in Person_Name) is
   begin
      if Count = Pool'Length then
         raise Queue_Error with "Buffer Full";  -- see 11.3
      end if;
      Pool(In_Index) := Person;
      In_Index       := (In_Index mod Pool'Length) + 1;
      Count          := Count + 1;
   end Append;
10/2
{AI95-00433-01}    entry Remove_First_Wait(Person : out Person_Name) Read(C : out Character)
      when Count > 0 is
   begin
      Remove_First(Person); C := Pool(Out_Index);
      Out_Index := (Out_Index mod Pool'Length) + 1;
      Count     := Count - 1;

   end Remove_First_Wait Read;
end Buffer
;
11/2
{AI95-00433-01}    procedure Remove_First(Person : out Person_Name) is
   begin
      if Count = 0 then
         raise Queue_Error with "Buffer Empty"; -- see 11.3
      end if;
      Person    := Pool(Out_Index);
      Out_Index := (Out_Index mod Pool'Length) + 1;
      Count     := Count - 1;
   end Remove_First;
12/2
{AI95-00433-01}    function Cur_Count return Natural is
   begin
       return Buffer.Count;
   end Cur_Count;
13/2
{AI95-00433-01}    function Max_Count return Natural is
   begin
       return Pool'Length;
   end Max_Count;
end Buffer;

Contents   Index   References   Search   Previous   Next 
Ada-Europe Ada 2005 and 2012 Editions sponsored in part by Ada-Europe