pragma Initialize_Scalars;
pragma Task_Dispatching_Policy (FIFO_Within_Priorities);
pragma Queuing_Policy (FIFO_Queuing);
with Ada.Dynamic_Priorities; use Ada.Dynamic_Priorities;
with Ada.Text_IO; use Ada.Text_IO;
with Exceptions; use Exceptions;
with Queues;
with System; use System;
procedure Queues_Test is
pragma Priority (Priority'Last);
type Sequence is (Ready, Set, Go);
type Modules is (Startup, Taxi, Takeoff, Climb, Cruise, Avoid,
Acrobatics, Looping, Inverted, Glidepath, Landing);
type Queue_Size is mod 2;
package Avionics_Queue is
new Queues (Element => Sequence, Queue_Enum => Modules, Index => Queue_Size);
use Avionics_Queue;
Queue : Protected_Queue;
task type Avionics_Module is
entry Provide_Id (Id : Modules);
end Avionics_Module;
Avionics : array (Modules) of Avionics_Module;
protected type Synchronizer (No_of_tasks : Positive) is
entry Wait_for_all (P : Priority);
private
Everybody_ready : Boolean := False;
end Synchronizer;
protected body Synchronizer is
entry Wait_for_all (P : Priority)
when Wait_for_all'Count = No_of_tasks or else Everybody_ready is
begin
Put_Line ("Some task released on priority: " & Priority'Image (P));
Everybody_ready := Wait_for_all'Count /= 0;
end Wait_for_all;
end Synchronizer;
Avionics_Synchronizer : Synchronizer (Avionics'Length + 1);
task body Avionics_Module is
Module : Modules;
begin
accept Provide_Id (Id : Modules) do
Module := Id;
end Provide_Id;
Set_Priority (Priority => Priority (Priority'First + Priority (Float (Modules'Pos (Module) - Modules'Pos (Modules'First))
* Float (Priority'Last - Priority'First) / Float (Modules'Pos (Modules'Last) - Modules'Pos (Modules'First)))));
Avionics_Synchronizer.Wait_for_all (Get_Priority);
declare
Accumulator : Natural := Natural (Get_Priority);
begin
for i in 1 .. 10_000 loop
for j in 1 .. 10_000 loop
Accumulator := Accumulator + Natural'Min (i / 10_000, j / 10_000);
end loop;
end loop;
Put_Line ("Task " & Modules'Image (Module) & " on priority: " & Priority'Image (Get_Priority)
& " accumulates: " & Natural'Image (Accumulator));
end;
declare
Item : Sequence;
begin
for Order in Sequence loop
Queue.Dequeue (Module) (Item);
Put_Line (Modules'Image (Module) & " on priority: " & Priority'Image (Get_Priority) & " removed " & Sequence'Image (Item) & " from queue.");
end loop;
end;
Avionics_Synchronizer.Wait_for_all (Get_Priority);
exception
when Exception_Id : others => Show_Exception (Exception_Id);
end Avionics_Module;
begin
for Module in Modules loop
Avionics (Module).Provide_Id (Module);
end loop;
Avionics_Synchronizer.Wait_for_all (Get_Priority);
declare
Accumulator : Natural := Natural (Get_Priority);
begin
for i in 1 .. 10_000 loop
for j in 1 .. 10_000 loop
Accumulator := Accumulator + Natural'Min (i / 10_000, j / 10_000);
end loop;
end loop;
Put_Line ("Main task on priority: " & Priority'Image (Get_Priority)
& " accumulates: " & Natural'Image (Accumulator));
end;
for Order in Sequence loop
Queue.Enqueue_For_All (Order);
Put_Line (Sequence'Image (Order) & " added to queue.");
end loop;
Avionics_Synchronizer.Wait_for_all (Get_Priority);
exception
when Exception_Id : others => Show_Exception (Exception_Id);
end Queues_Test;