Title here
Summary here
Our first example demonstrates non-blocking channel operations. In Ada, we can use the select
statement with an else
clause to implement non-blocking operations on entry calls and accept statements.
with Ada.Text_IO; use Ada.Text_IO;
procedure Non_Blocking_Operations is
task type Message_Task is
entry Send (Msg : in String);
entry Receive (Msg : out String);
end Message_Task;
task type Signal_Task is
entry Send (Sig : in Boolean);
entry Receive (Sig : out Boolean);
end Signal_Task;
task body Message_Task is
Message : String(1..20);
Length : Natural := 0;
begin
loop
select
accept Send (Msg : in String) do
Message(1..Msg'Length) := Msg;
Length := Msg'Length;
end Send;
or
accept Receive (Msg : out String) do
Msg := Message(1..Length);
end Receive;
or
terminate;
end select;
end loop;
end Message_Task;
task body Signal_Task is
Signal : Boolean := False;
begin
loop
select
accept Send (Sig : in Boolean) do
Signal := Sig;
end Send;
or
accept Receive (Sig : out Boolean) do
Sig := Signal;
end Receive;
or
terminate;
end select;
end loop;
end Signal_Task;
Messages : Message_Task;
Signals : Signal_Task;
begin
-- Here's a non-blocking receive. If a message is
-- available on Messages then the receive will be
-- executed. If not, it will immediately take the
-- else clause.
select
Messages.Receive (Msg => Message);
Put_Line ("received message " & Message);
else
Put_Line ("no message received");
end select;
-- A non-blocking send works similarly. Here the message
-- cannot be sent to the Messages task, because there's
-- no receiver ready. Therefore the else clause is selected.
declare
Msg : constant String := "hi";
begin
select
Messages.Send (Msg => Msg);
Put_Line ("sent message " & Msg);
else
Put_Line ("no message sent");
end select;
end;
-- We can use multiple alternatives above the else
-- clause to implement a multi-way non-blocking
-- select. Here we attempt non-blocking receives
-- on both Messages and Signals.
declare
Message : String(1..20);
Signal : Boolean;
begin
select
Messages.Receive (Msg => Message);
Put_Line ("received message " & Message);
or
Signals.Receive (Sig => Signal);
Put_Line ("received signal " & Boolean'Image(Signal));
else
Put_Line ("no activity");
end select;
end;
end Non_Blocking_Operations;
This Ada code demonstrates non-blocking operations using tasks and the select
statement. The Message_Task
and Signal_Task
types simulate channels, and the select
statements with else
clauses provide non-blocking behavior.
When you run this program, you’ll see output similar to:
no message received
no message sent
no activity
This output reflects that no messages or signals were available, demonstrating the non-blocking nature of the operations.