9.11 Example of Tasking and Synchronization

From OC Systems Wiki!
Jump to: navigation, search

Examples

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:

task Producer;

task body Producer is 
    Char : Character;
begin
    loop
        ... --  produce the next character Char
        Buffer.Write(Char);
        exit when Char = ASCII.EOT;
    end loop;
end Producer;

and the consuming task might have the following structure:

task Consumer;

task body Consumer is
    Char : Character;
begin
    loop
        Buffer.Read(Char); 
        exit when Char = ASCII.EOT;    
        ... --  consume the character Char
    end loop;
end Consumer;

The buffer object contains an internal pool of characters managed in a round-robin fashion. The pool has two indices, an In_Index denoting the space for the next input character and an Out_Index denoting the space for the next output character.

protected Buffer is
    entry Read (C out Character);
    entry Write(C in  Character);
private
    Pool      : String(1 .. 100); 
    Count     : Natural := 0; In_Index, Out_Index : Positive := 1;
end Buffer;

protected body Buffer is
    entry Write(C in Character)
        when Count < Pool'Length is 
    begin
        Pool(In_Index) := C;
        In_Index := (In_Index mod Pool'Length) + 1;
        Count    := Count + 1; 
    end Write;

    entry Read(C out Character)
        when Count > 0 is 
    begin
         C := Pool(Out_Index);
         Out_Index := (Out_Index mod Pool'Length) + 1;
         Count     := Count - 1; 
    end Read;
end Buffer;

Copyright © 1992,1993,1994,1995 Intermetrics, Inc.
Copyright © 2000 The MITRE Corporation, Inc. Ada Reference Manual