![[PREVIOUS]](lrm-prev.gif)
![[UP]](lrm-up.gif)
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;
![[INDEX]](lrm-idx.gif)
![[CONTENTS]](lrm-toc.gif)