Ein Buffer-Task wird sowohl vom Producer-Task als auch vom Consumer-Task aufgerufen und dient als Zwischenspeicher von Datenelementen (siehe Abb. 19.7).
Eine Realisierung durch ein generisches Paket könnte folgendermaßen aussehen:
generic
Die aufgeschobene Implementation des Task-Body's von Buffer könnte so realisiert werden:
separate (Generic_Buffer)
task body Buffer is
subtype Index_Type is positive range 1 .. size;
subtype Count_Type is natural range 0 .. size;
Buf: array (Index_Type) of Item;
Insert: Index_Type := 1;
Remove: Index_Type := 1;
Count: Count_Type := 0;
begin
loop
select
when Count
accept Enqueue (I: in item) do
Buf(Insert) := I;
end Enqueue;
Insert := (Insert mod Buf'LAST) + 1;
Count := Count + 1;
or
when Count
accept Dequeue (I: out item) do
I := Buf(Remove);
end Dequeue;
Remove := (Remove mod Buf'LAST) + 1;
Count := Count - 1;
or
terminate;
end select;
end loop;
end Buffer;
Da in diesem Fall der Buffer-Task nicht nur passiv ist, sondern auch keinerlei lokale Aktivitäten setzt, kann er auch als geschütztes Objekt realisiert werden. Die Spezifikation des generischen Paketes bleibt natürlich dieselbe, der Implementationsteil sieht dann allerdings folgendermaßen aus:
package body Generic_Buffer is
subtype Index_Type is positive range 1 .. size;
subtype Count_Type is positive range 0 .. size;
type item_array is array (Index_Type) of Item;
protected Buffer is
entry Enqueue (I: in item);
entry Dequeue (I: out item);
private
Buf: item_array;
Insert: Index_Type := 1;
Remove: Index_Type := 1;
Count: Count_Type := 0;
end Buffer;
protected body Buffer is separate;
procedure Enqueue (I: in item) is
begin
Buffer.Enqueue (I);
end Enqueue;
procedure Dequeue (I: out item) is
begin
Buffer.Dequeue (I);
end Dequeue;
end Generic_Buffer;
separate(Generic_Buffer)
protected body Buffer is
entry Enqueue (I: in item) when Count
begin
Buf(Insert) := I;
Insert := (Insert mod Buf'LAST) + 1;
Count := Count + 1;
end Enqueue;
entry Dequeue (I: out item) when Count
begin
I := Buf(Remove);
Remove := (Remove mod Buf'LAST) + 1;
Count := Count - 1;
end Dequeue;
end Buffer;
Johann Blieberger