Tasking
Display Service
Goal: create a simple service that displays messages to the user.
Steps:
Implement the
Display_Servicespackage.
Declare the task type
Display_Service.Implement the
Displayentry for strings.Implement the
Displayentry for integers.
Requirements:
Task type
Display_Serviceuses theDisplayentry to display messages to the user.There are two versions of the
Displayentry:
One that receives messages as a string parameter.
One that receives messages as an
Integerparameter.When a message is received via a
Displayentry, it must be displayed immediately to the user.
package Display_Services is
end Display_Services;
package body Display_Services is
end Display_Services;
with Ada.Command_Line; use Ada.Command_Line;
with Ada.Text_IO; use Ada.Text_IO;
with Display_Services; use Display_Services;
procedure Main is
type Test_Case_Index is (Display_Service_Chk);
procedure Check (TC : Test_Case_Index) is
Display : Display_Service;
begin
case TC is
when Display_Service_Chk =>
Display.Display ("Hello");
delay 0.5;
Display.Display ("Hello again");
delay 0.5;
Display.Display (55);
delay 0.5;
end case;
end Check;
begin
if Argument_Count < 1 then
Put_Line ("ERROR: missing arguments! Exiting...");
return;
elsif Argument_Count > 1 then
Put_Line ("Ignoring additional arguments...");
end if;
Check (Test_Case_Index'Value (Argument (1)));
end Main;
Event Manager
Goal: implement a simple event manager.
Steps:
Implement the
Event_Managerspackage.
Declare the task type
Event_Manager.Implement the
Startentry.Implement the
Evententry.
Requirements:
The event manager has a similar behavior as an alarm
The sole purpose of this event manager is to display the event ID at the correct time.
After the event ID is displayed, the task must finish.
The event manager (
Event_Managertype) must have two entries:
Start, which starts the event manager with an event ID;
Event, which delays the task until a certain time and then displays the event ID as a user message.The format of the user message displayed by the event manager is
Event #<event_id>.
You should use
Natural'Imageto display the ID (as indicated in the body of theEvent_Managerspackage below).
Remarks:
In the
Startentry, you can use theNaturaltype for the ID.In the
Evententry, you should use theTimetype from theAda.Real_Timepackage for the time parameter.Note that the test application below creates an array of event managers with different delays.
package Event_Managers is
end Event_Managers;
package body Event_Managers is
-- Don't forget to display the event ID:
--
-- Put_Line ("Event #" & Natural'Image (Event_ID));
end Event_Managers;
with Ada.Command_Line; use Ada.Command_Line;
with Ada.Text_IO; use Ada.Text_IO;
with Event_Managers; use Event_Managers;
with Ada.Real_Time; use Ada.Real_Time;
procedure Main is
type Test_Case_Index is (Event_Manager_Chk);
procedure Check (TC : Test_Case_Index) is
Ev_Mng : array (1 .. 5) of Event_Manager;
begin
case TC is
when Event_Manager_Chk =>
for I in Ev_Mng'Range loop
Ev_Mng (I).Start (I);
end loop;
Ev_Mng (1).Event (Clock + Seconds (5));
Ev_Mng (2).Event (Clock + Seconds (3));
Ev_Mng (3).Event (Clock + Seconds (1));
Ev_Mng (4).Event (Clock + Seconds (2));
Ev_Mng (5).Event (Clock + Seconds (4));
end case;
end Check;
begin
if Argument_Count < 1 then
Put_Line ("ERROR: missing arguments! Exiting...");
return;
elsif Argument_Count > 1 then
Put_Line ("Ignoring additional arguments...");
end if;
Check (Test_Case_Index'Value (Argument (1)));
end Main;
Generic Protected Queue
Goal: create a queue container using a protected type.
Steps:
Implement the generic package
Gen_Queues.
Declare the protected type
Queue.Implement the
Emptyfunction.Implement the
Fullfunction.Implement the
Pushentry.Implement the
Popentry.
Requirements:
These are the formal parameters for the generic package
Gen_Queues:
a formal modular type;
This modular type should be used by the
Queueto declare an array that stores the elements of the queue.The modulus of the modular type must correspond to the maximum number of elements of the queue.
the data type of the elements of the queue.
Select a formal parameter that allows you to store elements of any data type in the queue.
These are the operations of the
Queuetype:
Function
Emptyindicates whether the queue is empty.Function
Fullindicates whether the queue is full.Entry
Pushstores an element in the queue.Entry
Popremoves an element from the queue and returns the element via output parameter.
Remarks:
In this exercise, we create a queue container by declaring and implementing a protected type (
Queue) as part of a generic package (Gen_Queues).As a bonus exercise, you can analyze the body of the
Queue_Testspackage and understand how theQueuetype is used there.
In particular, the procedure
Concurrent_Testimplements two tasks:T_ProducerandT_Consumer. They make use of the queue concurrently.
package Gen_Queues is
end Gen_Queues;
package body Gen_Queues is
end Gen_Queues;
package Queue_Tests is
procedure Simple_Test;
procedure Concurrent_Test;
end Queue_Tests;
with Ada.Text_IO; use Ada.Text_IO;
with Gen_Queues;
package body Queue_Tests is
Max : constant := 10;
type Queue_Mod is mod Max;
procedure Simple_Test is
package Queues_Float is new Gen_Queues (Queue_Mod, Float);
Q_F : Queues_Float.Queue;
V : Float;
begin
V := 10.0;
while not Q_F.Full loop
Q_F.Push (V);
V := V + 1.5;
end loop;
while not Q_F.Empty loop
Q_F.Pop (V);
Put_Line ("Value from queue: " & Float'Image (V));
end loop;
end Simple_Test;
procedure Concurrent_Test is
package Queues_Integer is new Gen_Queues (Queue_Mod, Integer);
Q_I : Queues_Integer.Queue;
task T_Producer;
task T_Consumer;
task body T_Producer is
V : Integer := 100;
begin
for I in 1 .. 2 * Max loop
Q_I.Push (V);
V := V + 1;
end loop;
end T_Producer;
task body T_Consumer is
V : Integer;
begin
delay 1.5;
while not Q_I.Empty loop
Q_I.Pop (V);
Put_Line ("Value from queue: " & Integer'Image (V));
delay 0.2;
end loop;
end T_Consumer;
begin
null;
end Concurrent_Test;
end Queue_Tests;
with Ada.Command_Line; use Ada.Command_Line;
with Ada.Text_IO; use Ada.Text_IO;
with Queue_Tests; use Queue_Tests;
procedure Main is
type Test_Case_Index is (Simple_Queue_Chk,
Concurrent_Queue_Chk);
procedure Check (TC : Test_Case_Index) is
begin
case TC is
when Simple_Queue_Chk =>
Simple_Test;
when Concurrent_Queue_Chk =>
Concurrent_Test;
end case;
end Check;
begin
if Argument_Count < 1 then
Put_Line ("ERROR: missing arguments! Exiting...");
return;
elsif Argument_Count > 1 then
Put_Line ("Ignoring additional arguments...");
end if;
Check (Test_Case_Index'Value (Argument (1)));
end Main;