Consider a data item which is to be shared between a single producer and a single consumer. The producer is a periodic task which reads a sensor and writes the value to the shared data item. The consumer is a sporadic task which wishes to take the latest value placed in the shared data item by the producer.
The following package claims to provide a generic algorithm with which the producer and consumer can communicate safely, without the need for mutual exclusion or busy waiting.
generic
type Data is private;
Initialvalue : Data;
package Simpsons_Algorithm is
procedure Write(Item: Data); -- non-blocking
procedure Read (Item : out Data); -- non-blocking
end Simpsons_Algorithm;
package body Simpsons_Algorithm is
type slot is (First, Second);
Fourslot : array (Slot, Slot) of Data :=
(First $\Rightarrow$ (Initialvalue, Initialvalue),
Second $=>$ (Initialvalue, Initialvalue));
Nextslot : array(Slot) of slot := (First, First);
Latest : Slot : = First;
Reading : Slot := First;
procedure Write(Item : Data) is
Pair, Index : Slot;
begin
if Reading $=$ First then
Pair := Second;
else
Pair := First;
end if;
if NEXT_SLOT (Pair) = First then
Index := Second;
else
Index := First;
end if;
Fourslot(Pair, Index) $:=$ Item;
Nextslot(Pair) := Index;
Latest : = Pair;
end write;
procedure Read(Item : out Data) is
Pair, Index : Slot;
begin
Pair : = Latest;
Reading := Pair;
Index := Nextslot(Pair);
Item := Fourslot(Pair, Index);
end Read;
end Simpsons_Algorithm;
Describe carefully how this algorithm works by explaining what happens when:
(1) a Write is followed by a Read
(2) a Read is preempted by a Write
(3) a Write is preempted by a Read
(4) a Read is preempted by more than one Write
(6) a Write is preempted by more than one Read
Comment on how the algorithm trades off safe communication against data freshness.
Many compilers optimize code so that frequently accessed variables are held in registers local to a task. In this context, comment on whether the above algorithm's claim of safe communication is justifiable. Are there any changes to the algorithm needed to make it work for all implementations of Ada?