Tasking
Display Service
Goal: create a simple service that displays messages to the user.
Steps:
Implement the
Display_Services
package.
Declare the task type
Display_Service
.Implement the
Display
entry for strings.Implement the
Display
entry for integers.
Requirements:
Task type
Display_Service
uses theDisplay
entry to display messages to the user.There are two versions of the
Display
entry:
One that receives messages as a string parameter.
One that receives messages as an
Integer
parameter.When a message is received via a
Display
entry, 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_Managers
package.
Declare the task type
Event_Manager
.Implement the
Start
entry.Implement the
Event
entry.
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_Manager
type) 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'Image
to display the ID (as indicated in the body of theEvent_Managers
package below).
Remarks:
In the
Start
entry, you can use theNatural
type for the ID.In the
Event
entry, you should use theTime
type from theAda.Real_Time
package 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
Empty
function.Implement the
Full
function.Implement the
Push
entry.Implement the
Pop
entry.
Requirements:
These are the formal parameters for the generic package
Gen_Queues
:
a formal modular type;
This modular type should be used by the
Queue
to 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
Queue
type:
Function
Empty
indicates whether the queue is empty.Function
Full
indicates whether the queue is full.Entry
Push
stores an element in the queue.Entry
Pop
removes 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_Tests
package and understand how theQueue
type is used there.
In particular, the procedure
Concurrent_Test
implements two tasks:T_Producer
andT_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;