Non Blocking Channel Operations in Ada 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.