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;
Address any questions or comments to firstname.lastname@example.org.