with Random_Tools; use Random_Tools; with Ada.Float_Text_IO; with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; with Unbounded_Strings; use Unbounded_Strings; with convert_unbounded_strings; use unbounded_strings.unbounded_string_list_package; with architecture_factory; use architecture_factory; with Ada.text_IO; use Ada.text_IO; with Ada.Integer_text_IO; use Ada.Integer_text_IO; with Ada.Float_Text_IO; use Ada.Float_Text_IO; with Task_Set; use Task_Set; with Tasks; use Tasks; with Systems; use Systems; with Processors; use Processors; with Processor_Set; use Processor_Set; with processor_interface; use processor_interface; with Core_Units; use Core_Units; use Core_Units.Core_Units_Table_Package; with Scheduler_Interface; use Scheduler_Interface; with Address_Spaces; use Address_Spaces; with Address_Space_Set; use Address_Space_Set; with Call_Framework; use Call_Framework; with Call_Framework_Interface; use Call_Framework_Interface; use Call_Framework_Interface.Framework_Response_Package; use Call_Framework_Interface.Framework_Request_Package; with Call_Scheduling_Framework; use Call_Scheduling_Framework; with natural_util; use natural_util; with Ada.Numerics.Aux; use Ada.Numerics.Aux; with feasibility_test.feasibility_interval; use feasibility_test.feasibility_interval; with Pipe_Commands; use Pipe_Commands; with Ada.Text_IO; use Ada.Text_IO; with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; with Ada.Text_IO.Unbounded_IO; use Ada.Text_IO.Unbounded_IO; with Ada.Directories; use Ada.Directories; with Paes_For_Clustering; use Paes_For_Clustering; with integer_util; use integer_util; package body Task_Clustering_Rules is ------------------------------------------- -- Generate_initial_schedulable_task_set -- ------------------------------------------- procedure Generate_initial_schedulable_task_set (my_tasks : in out Tasks_Set; N : in Integer; U : in Float) is schedulable : boolean := false; use Ada.Float_Text_IO; i : Integer; A_capacity : natural := 0; A_period : natural := 0; A_deadline : natural := 0; u_array : Random_Tools.Float_Array(0..N-1); flag : Boolean := true; FileStream : stream; command : unbounded_String; F : Ada.Text_IO.File_Type; line : unbounded_String; Buffer : unbounded_String; hyperperiod : integer; hyperperiod_too_big : boolean := true; begin Call_Framework.initialize (False); -- Generate Utilizations of tasks according -- the classic UUnifast method [BINI and BUTTAZZO] while (flag) loop u_array:=Gen_UUniFast(n => N, U => U); flag := false; for i in 0..N-1 loop if(u_array(i) < 0.01) then -- if(u_array(i) < 0.0098) then --if(u_array(i) < 0.03) then --if(u_array(i) < 0.0125) then flag := true; end if; end loop; end loop; Put_Line("Utilizations of tasks are generated with UUnifast : "); for i in 0..N-1 loop Put_Line ("U" & i'img & "= " & u_array(i)'img); end loop; while not schedulable loop -- Determine capacities, periods and deadlines while hyperperiod_too_big loop Initialize (my_tasks); i := 1; while (i <= N) loop A_capacity := 0; A_period := 0; A_deadline := 0; while(A_capacity <=0 or A_period <=0) loop A_period := Random_Integer(n1 => 1, n2 => 15); --A_period := Random_Integer(n1 => 5, -- n2 => 15); --A_period := Random_Integer(n1 => 5, -- n1 => 4 -- n2 => 18); A_period := A_period * 10; -- Difference between Ceiling and Floor -- Float'Ceiling(1.5) = 2.0 -- Float'Floor(1.5) = 1.0 A_capacity := Integer(Float'Floor(Float(A_period)*u_array(i-1))); A_deadline := A_period; Put_Line ("C" & To_String(Suppress_Space (To_Unbounded_String (i'Img))) & " = " & A_capacity'img &" T" & To_String(Suppress_Space (To_Unbounded_String (i'Img))) & " = " & A_period'img); end loop; Add_Task(My_Tasks => my_tasks, Name => Suppress_Space (To_Unbounded_String ("Task" & i'Img)), Cpu_Name => To_Unbounded_String("processor1"), Address_Space_Name => To_Unbounded_String("addr1"), Task_Type => Periodic_Type, Start_Time => 0, Capacity => A_capacity, Period => A_period, Deadline => A_deadline, Jitter => 0, Blocking_Time => 0, Priority => Task_priority, Criticality => 0, Policy => Sched_policy); i := i+1; end loop; Hyperperiod := Scheduling_Period (my_tasks, to_unbounded_string("processor1")); Put_Line ("The hyperperiod of the generated task set is : " & Hyperperiod'img); if Hyperperiod < 40000 then Hyperperiod_too_big := false; end if; end loop; Build_xml_model (my_tasks, "candidate_solution.xmlv3"); -- command := To_Unbounded_String("../../../../../../../call_cheddar_d " command := To_Unbounded_String("/media/DATA/These_Rahma/CHEDDAR/trunk/src/call_cheddar_d " & Hyperperiod'img & " candidate_solution.xmlv3"); FileStream := execute(To_String(command), read_file); loop begin Buffer := read_next(FileStream); exception when Pipe_Commands.End_of_file => exit; end; end loop; close(FileStream); Open(F, Ada.Text_IO.In_File,"Output.txt"); line := To_Unbounded_String(get_line(F)); line := Unbounded_Slice(line,1,3); if line = "sch" then schedulable := true; Initial_tasks_set := my_tasks; Put_Line ("The generated task set is schedulable"); line := To_Unbounded_String(get_line(F)); line := Unbounded_Slice(line, index(line,"=") + 3, length(line)); Nb_preemption_of_the_candidate_sol := integer'Value(to_string(Unbounded_Slice(line,1,length(line)))); put_line("Nb_preemptions = " & Nb_preemption_of_the_candidate_sol'Img); line := To_Unbounded_String(get_line(F)); line := Unbounded_Slice(line, index(line,"=") + 3, length(line)); Sum_laxities_of_the_candidate_sol := integer'Value (to_string(Unbounded_Slice(line,1,length(line)))); put_line("sum_lax = " & Sum_laxities_of_the_candidate_sol'Img); line := To_Unbounded_String(get_line(F)); line := Unbounded_Slice(line, index(line,"=") + 3, length(line)); Min_laxities_of_the_candidate_sol := integer'Value (to_string(Unbounded_Slice(line,1,length(line)))); put_line("Min_lax = " & Min_laxities_of_the_candidate_sol'Img); else Put_Line ("The generated task set is not schedulable"); for i in 1..genes loop A_capacity := Task_Set.Get (My_Tasks => my_tasks, Task_Name => Suppress_Space (To_Unbounded_String ("Task" & i'Img)), Param_Name => Capacity); A_period := Task_Set.Get (My_Tasks => my_tasks, Task_Name => Suppress_Space (To_Unbounded_String ("Task" & i'Img)), Param_Name => Period); A_deadline := Task_Set.Get (My_Tasks => my_tasks, Task_Name => Suppress_Space (To_Unbounded_String ("Task" & i'Img)), Param_Name => Deadline); Ada.text_IO.Put (" C" & i'Img & " = " & A_capacity'Img); Ada.text_IO.Put (" T" & i'Img & " = " & A_period'Img); Ada.text_IO.Put (" D" & i'Img & " = " & A_deadline'Img); New_Line; end loop; end if; Close(F); end loop; end Generate_initial_schedulable_task_set; --------------------- -- number_of_tasks -- --------------------- function Number_of_tasks (s : in solution) return integer is permutation : integer := 1; var : chrom_type; nb_tasks, tmp : integer; begin -- assignment of the table var with elements of s.chrom for i in 1..genes loop var(i) := s.chrom(i); end loop; -- sorting elements of var in the increasing order while permutation = 1 loop permutation := 0; for i in 1..genes-1 loop if (var(i) > var(i+1)) then tmp := var(i); var(i) := var(i+1); var(i+1) := tmp; permutation := 1; end if; end loop; end loop; nb_tasks := genes; for i in 1..genes-1 loop if (var(i) = var(i+1)) then nb_tasks := nb_tasks - 1; end if; end loop; return nb_tasks; end Number_of_tasks; ------------------------------ -- Appling_clustering_rules -- ------------------------------ function Appling_clustering_rules (s : in solution) return Tasks_Set is A_Tasks_set : Tasks_Set; A_Task : Periodic_Task; nb_tasks,k : integer; period_i, period_j : natural; capacity_i, capacity_j : natural; deadline_i, deadline_j : natural; var : chrom_type; Initial_set : Tasks_Set := Initial_tasks_set; begin nb_tasks := number_of_tasks(s); Initialize (A_Task); for i in 1..genes loop var(i) := 0; end loop; k := 1; for i in 1..genes loop Initialize (A_Task); if var(i) = 0 then var (i) := 1; period_i := Get (My_Tasks => Initial_set, Task_Name => Suppress_Space (To_Unbounded_String ("Task" & i'Img)), Param_Name => Period); capacity_i := Get (My_Tasks => Initial_set, Task_Name => Suppress_Space (To_Unbounded_String ("Task" & i'Img)), Param_Name => Capacity); deadline_i := Get (My_Tasks => Initial_set, Task_Name => Suppress_Space (To_Unbounded_String ("Task" & i'Img)), Param_Name => Deadline); for j in i+1 .. genes loop if (s.chrom(i) = s.chrom(j)) then var (j) := 1; period_j := Get(My_Tasks => Initial_set, Task_Name => Suppress_Space (To_Unbounded_String ("Task" & j'Img)), Param_Name => Period); capacity_j := Get(My_Tasks => Initial_set, Task_Name => Suppress_Space (To_Unbounded_String ("Task" & j'Img)), Param_Name => Capacity); deadline_j := Get(My_Tasks => Initial_set, Task_Name => Suppress_Space (To_Unbounded_String ("Task" & j'Img)), Param_Name => Deadline); if (A_Task.period = 0) then A_Task.capacity := capacity_i + capacity_j; if period_i > period_j then A_Task.period := period_j; else A_Task.period := period_i; end if; if deadline_i > deadline_j then A_Task.deadline := deadline_j; else A_Task.deadline := deadline_i; end if; else A_Task.capacity := A_Task.capacity + capacity_j; if A_Task.period > period_j then A_Task.period := period_j; end if; if A_Task.deadline > deadline_j then A_Task.deadline := deadline_j; end if; end if; end if; end loop; if (A_Task.period = 0) then A_Task.period := period_i; A_Task.capacity := capacity_i; A_Task.deadline := deadline_i; end if; Add_Task(My_Tasks => A_Tasks_set, Name => Suppress_Space (To_Unbounded_String ("Task" & k'Img)), Cpu_Name => To_Unbounded_String("processor1"), Address_Space_Name => To_Unbounded_String("addr1"), Task_Type => Periodic_Type, Start_Time => 0, Capacity => A_Task.capacity, Period => A_Task.period, Deadline => A_Task.deadline, Jitter => 0, Blocking_Time => 0, Priority => Task_priority, Criticality => 0, Policy => Sched_policy); k := k + 1; end if; end loop; return A_Tasks_set; end Appling_clustering_rules; --------------------- -- Build_xml_model -- --------------------- procedure Build_xml_model (my_tasks : in Tasks_Set; file_name : string) is sys : system; a_core : core_unit_ptr; begin Initialize(A_System => sys); Add_Address_Space(sys.address_spaces, to_unbounded_string("addr1"), to_unbounded_string("processor1"), 0, 0, 0, 0); Add_core_unit(My_core_units => sys.core_units, A_core_unit => a_core, Name => to_unbounded_string("core1"), Is_Preemptive => preemptive, Quantum => 0, speed => 1.0, capacity => 0, period => 0, Priority => Task_priority, File_Name => to_unbounded_string(""), A_Scheduler => The_scheduler); Add_Processor(My_Processors => sys.processors, Name => to_unbounded_string("processor1"), A_Network => to_unbounded_string("a_network"), a_Core => a_core); sys.Tasks := my_tasks; Write_To_Xml_File(A_System => sys, File_Name => file_name); end Build_xml_model; ----------------------- -- Is_sol_consistent -- ----------------------- function Is_sol_consistent (s : in solution) return boolean is Is_consistent : boolean; min_periods : Integer; nb_tasks : Integer; gcd_periods : Integer; i : Integer; nb_functions_in_task_i : Integer; periods_array : array (0..genes-1) of Integer; Initial_set : Tasks_Set := Initial_tasks_set; begin Is_consistent := true; nb_tasks := number_of_tasks(s); i := 1; while (i<= nb_tasks) and Is_consistent loop nb_functions_in_task_i := 0; for j in 1 .. genes loop if (s.chrom(j) = i) then nb_functions_in_task_i := nb_functions_in_task_i + 1; periods_array (nb_functions_in_task_i) := Get(My_Tasks => Initial_set, Task_Name => Suppress_Space (To_Unbounded_String ("Task" & j'Img)), Param_Name => Period); end if; end loop; if (nb_functions_in_task_i = 2) then if ( periods_array(1) < periods_array(2) ) then min_periods := periods_array(1); else min_periods := periods_array(2); end if; gcd_periods := integer_util.gcd (periods_array(1) , periods_array(2)); if (min_periods /= gcd_periods) then Is_consistent := false; end if; elsif (nb_functions_in_task_i > 2) then min_periods := periods_array(1); gcd_periods := integer_util.gcd (periods_array(1) , periods_array(2)); for j in 2 .. nb_functions_in_task_i loop if (periods_array(j) < min_periods) then min_periods := periods_array(j); end if; if (j < nb_functions_in_task_i) then gcd_periods := integer_util.gcd (gcd_periods, periods_array(j+1)); end if; end loop; if (min_periods /= gcd_periods) then Is_consistent := false; end if; else Is_consistent := true; end if; i := i + 1; end loop; return Is_consistent; end Is_sol_consistent; end Task_Clustering_Rules;