with Ada.Text_IO; use Ada.Text_IO;
procedure Link_Tasks is
type Task_Range is mod 5;
type Messages is new Natural;
task type Task_Linked_By_Global_Array is
entry Link_To (This_Task,
Next_Task : Task_Range);
entry Synchronous_Message (Message : Messages);
end Task_Linked_By_Global_Array;
type Task_Linked_By_Reference;
type Task_Linked_By_Reference_P is access all Task_Linked_By_Reference;
task type Task_Linked_By_Reference is
entry Link_To (This_Task : Task_Range;
Next_Task : Task_Linked_By_Reference_P);
entry Synchronous_Message (Message : Messages);
end Task_Linked_By_Reference;
Tasks_Linked_By_Global_Array : array (Task_Range) of Task_Linked_By_Global_Array;
Tasks_Linked_By_Reference : array (Task_Range) of aliased Task_Linked_By_Reference;
task body Task_Linked_By_Global_Array is
This_Task_Ix,
Next_Task_Ix : Task_Range;
begin
accept Link_To (This_Task, Next_Task : Task_Range) do
This_Task_Ix := This_Task;
Next_Task_Ix := Next_Task;
end Link_To;
declare
The_Last_Word : Messages := Messages (Task_Range'First);
procedure Send_Word (Word : in out Messages) is
begin
Word := Word + Messages (This_Task_Ix);
Put_Line ("Task " & Task_Range'Image (This_Task_Ix) & " sends (index) :" & Messages'Image (Word));
Tasks_Linked_By_Global_Array (Next_Task_Ix).Synchronous_Message (Word);
end Send_Word;
begin
if This_Task_Ix = Task_Range'First then
Send_Word (The_Last_Word);
accept Synchronous_Message (Message : Messages) do
The_Last_Word := Message;
end Synchronous_Message;
Put_Line ("Task " & Task_Range'Image (This_Task_Ix) & " received (index) :" & Messages'Image (The_Last_Word));
else
accept Synchronous_Message (Message : Messages) do
The_Last_Word := Message;
end Synchronous_Message;
Put_Line ("Task " & Task_Range'Image (This_Task_Ix) & " received (index) :" & Messages'Image (The_Last_Word));
Send_Word (The_Last_Word);
end if;
end;
end Task_Linked_By_Global_Array;
task body Task_Linked_By_Reference is
This_Task_Ix : Task_Range;
Next_Task_P : Task_Linked_By_Reference_P;
begin
accept Link_To (This_Task : Task_Range; Next_Task : Task_Linked_By_Reference_P) do
This_Task_Ix := This_Task;
Next_Task_P := Next_Task;
end Link_To;
declare
The_Last_Word : Messages := Messages (Task_Range'First);
procedure Send_Word (Word : in out Messages) is
begin
Word := Word + Messages (This_Task_Ix);
Put_Line ("Task " & Task_Range'Image (This_Task_Ix) & " sends (reference) :" & Messages'Image (Word));
Next_Task_P.all.Synchronous_Message (Word);
end Send_Word;
begin
if This_Task_Ix = Task_Range'First then
Send_Word (The_Last_Word);
accept Synchronous_Message (Message : Messages) do
The_Last_Word := Message;
end Synchronous_Message;
Put_Line ("Task " & Task_Range'Image (This_Task_Ix) & " received (reference) :" & Messages'Image (The_Last_Word));
else
accept Synchronous_Message (Message : Messages) do
The_Last_Word := Message;
end Synchronous_Message;
Put_Line ("Task " & Task_Range'Image (This_Task_Ix) & " received (reference) :" & Messages'Image (The_Last_Word));
Send_Word (The_Last_Word);
end if;
end;
end Task_Linked_By_Reference;
begin
for Task_Ix in Tasks_Linked_By_Global_Array'Range loop
Tasks_Linked_By_Global_Array (Task_Ix).Link_To (Task_Ix, Task_Ix + 1);
end loop;
for Task_Ix in Tasks_Linked_By_Reference'Range loop
Tasks_Linked_By_Reference (Task_Ix).Link_To (Task_Ix, Tasks_Linked_By_Reference (Task_Ix + 1)'Access);
end loop;
end Link_Tasks;