9.12. Example of Tasking

[PREVIOUS][UP]

The following example defines a buffering task 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 may contain the statements

    loop
       --  produce the next character CHAR
       BUFFER.WRITE(CHAR);
       exit when CHAR = ASCII.EOT;
    end loop;   

and the consuming task may contain the statements

    loop
       BUFFER.READ(CHAR);
       --  consume the character CHAR
       exit when CHAR = ASCII.EOT;
    end loop; 

The buffering task contains an internal pool of characters processed 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.

    task BUFFER is
       entry READ (C : out CHARACTER);
       entry WRITE(C : in  CHARACTER);
    end; 

    task body BUFFER is
       POOL_SIZE : constant INTEGER := 100;
       POOL      : array(1 .. POOL_SIZE) of CHARACTER;
       COUNT     : INTEGER range 0 .. POOL_SIZE := 0;
       IN_INDEX, OUT_INDEX : INTEGER range 1 .. POOL_SIZE := 1;
    begin
       loop
          select
             when COUNT < POOL_SIZE =>
                accept WRITE(C : in CHARACTER) do
                   POOL(IN_INDEX) := C;
                end;
                IN_INDEX := IN_INDEX mod POOL_SIZE + 1;
                COUNT    := COUNT + 1;
          or when COUNT > 0 =>
                accept READ(C : out CHARACTER) do
                   C := POOL(OUT_INDEX);
                end;
                OUT_INDEX := OUT_INDEX mod POOL_SIZE + 1;
                COUNT     := COUNT - 1;
          or
             terminate;
          end select;  
       end loop;
    end BUFFER;                                                       

[PREVIOUS][UP][NEXT]


[INDEX][CONTENTS]