------------------------------------------------------------------------------ ------------------------------------------------------------------------------ -- Cheddar is a GNU GPL real-time scheduling analysis tool. -- This program provides services to automatically check schedulability and -- other performance criteria of real-time architecture models. -- -- Copyright (C) 2002-2020, Frank Singhoff, Alain Plantec, Jerome Legrand, -- Hai Nam Tran, Stephane Rubini -- -- The Cheddar project was started in 2002 by -- Frank Singhoff, Lab-STICC UMR 6285, Université de Bretagne Occidentale -- -- Cheddar has been published in the "Agence de Protection des Programmes/France" in 2008. -- Since 2008, Ellidiss technologies also contributes to the development of -- Cheddar and provides industrial support. -- -- The full list of contributors and sponsors can be found in AUTHORS.txt and SPONSORS.txt -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 2 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- -- -- Contact : cheddar@listes.univ-brest.fr -- ------------------------------------------------------------------------------ -- Last update : -- $Rev$ -- $Date$ -- $Author: singhoff $ ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ 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 Ada.Numerics.Elementary_Functions; use Ada.Numerics.Elementary_Functions; with Ada.Strings; use Ada.Strings; with Ada.Strings.Fixed; use Ada.Strings.Fixed; with Ada.Numerics.Float_Random ; use Ada.Numerics.Float_Random ; with unbounded_strings; use unbounded_strings; with Tasks; use Tasks; with Task_Set; use Task_Set; 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 feasibility_test.feasibility_interval; use feasibility_test.feasibility_interval; 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 Processors; use Processors; with Processor_Set; use Processor_Set; with processor_interface; use processor_interface; with Systems; use Systems; 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 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 GNAT.OS_Lib; use GNAT.OS_Lib; with paes_for_clustering; use paes_for_clustering; with Task_Clustering_Rules; use Task_Clustering_Rules; with integer_util; use integer_util; with Debug; use Debug; package body exact_front_computation is ------------------- -- enumerate_sol -- ------------------- procedure enumerate_sol is A_sol,A_sol_norm : solution; m : chrom_type; b : boolean; NB_consistent_solutions : Integer := 0; NB_consistent_and_sched_solutions : Integer := 0; New_Task_set : Tasks_Set; New_nb_tasks : integer; FileStream : stream; command : unbounded_String; F : Ada.Text_IO.File_Type; line : unbounded_String; Buffer : unbounded_String; iter : integer; A_system : System; eidx : integer := 0; begin Call_Framework.initialize (False); Create_system(A_system); iter := 1; for i in 1..genes loop A_sol.chrom(i) := 1; m(i) := 1; end loop; Put_Debug(" ------------------ "); Put_Debug(" iteration = " & iter'Img); Put_Debug(" ------------------ "); Put_Debug(" ");--New_Line; Put_Debug ("The candidate solution is : "); print_debug_genome(A_sol); Put_Debug(" ");--New_Line; New_Line; -- normalize the candidate solution A_sol_norm := A_sol; normalize(A_sol_norm); Put_Debug(" ");--New_Line; Put_Debug ("After normalization the candidate solution is : "); print_debug_genome(A_sol_norm); Put_Debug(" ");--New_Line; ---------------------------------------------------------------------------------------- -- After generating a candidate solution, we shoud verify : -- 1) If it is consistent or not i.e two non-harmonic functions -- which are grouped alone in the same task. -- 2) If it was a consistent solution then we should verify its schedulability -- by calling the Cheddar tool to simulate the scheduling of the candidate task set -- Else, we do not check the schedulability of this candidate solution ----------------------------------------------------------------------------------------- If Check_Consistency_Of_A_Solution (A_sol_norm) then Put_Debug (" The candidate solution is consistent and then we check the schedulability"); NB_consistent_solutions := NB_consistent_solutions + 1; -- check the schedulability Appling_clustering_rules (A_System, A_sol_norm); New_nb_tasks := Number_of_tasks (A_sol_norm); command := To_Unbounded_String("candidate_solution" & eidx'Img & ".xmlv3"); Write_To_Xml_File(A_System => A_System, File_Name => To_String(command)); command := To_Unbounded_String("~/call_cheddar " & Hyperperiod_of_Initial_Taskset'img & " candidate_solution\" & eidx'Img & ".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" & eidx'Img & ".txt"); line := To_Unbounded_String(get_line(F)); Close(F); if line = "schedulability : true" then Put_Debug("**The candidate task set is schedulable**"); evaluate_for_clustering (A_sol_norm,0); NB_consistent_and_sched_solutions := NB_consistent_and_sched_solutions + 1; All_consistent_valid_solutions.Append (A_sol_norm); else Put_Debug("**The candidate task set is NOT schedulable**"); end if; else Put_Debug (" The candidate solution is NOt consistent and then " & " we do not check the schedulabily"); end if; -- Generate the next candidate next(A_sol, m, genes, b); while b loop iter := iter + 1; Put_Debug(" ------------------ "); Put_Debug(" iteration = " & iter'Img); Put_Debug(" ------------------ "); Put_Debug(" ");--New_Line; Put_Debug ("The candidate solution is : "); print_debug_genome(A_sol); Put_Debug(" ");--New_Line; -- normalize the candidate solution A_sol_norm := A_sol; normalize(A_sol_norm); Put_Debug(" ");--New_Line; Put_Debug ("After normalization of the candidate solution is : "); print_debug_genome(A_sol_norm); Put_Debug(" ");--New_Line; ---------------------------------------------------------------------------------------- -- After generating a candidate solution, we shoud verify : -- 1) If it is consistent or not i.e two non-harmonic functions -- which are grouped alone in the same task. -- 2) If it was a consistent solution then we should verify its schedulability -- by calling the Cheddar tool to simulate the scheduling of the candidate task set -- Else, we do not check the schedulability of this candidate solution ----------------------------------------------------------------------------------------- If Check_Consistency_Of_A_Solution (A_sol_norm) then Put_Debug (" The candidate solution is consistent and then we check the schedulability"); NB_consistent_solutions := NB_consistent_solutions + 1; -- check the schedulability Appling_clustering_rules (A_System, A_sol_norm); New_nb_tasks := Number_of_tasks (A_sol_norm); command := To_Unbounded_String("candidate_solution" & eidx'Img & ".xmlv3"); Write_To_Xml_File(A_System => A_System, File_Name => To_String(command)); command := To_Unbounded_String("~/call_cheddar " & Hyperperiod_of_Initial_Taskset'img & " candidate_solution\" & eidx'Img & ".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" & eidx'Img & ".txt"); line := To_Unbounded_String(get_line(F)); close(F); if line = "schedulability : true" then Put_Debug("**The candidate task set is schedulable**"); evaluate_for_clustering (A_sol_norm,0); NB_consistent_and_sched_solutions := NB_consistent_and_sched_solutions + 1; All_consistent_valid_solutions.Append (A_sol_norm); else Put_Debug("**The candidate task set is NOT schedulable**"); end if; else Put_Debug (" The candidate solution is NOt consistent and then " & " we do not check the schedulabily"); end if; next(A_sol, m, genes, b); end loop; nb_consistent := NB_consistent_solutions; nb_consistent_sched := NB_consistent_and_sched_solutions; end enumerate_sol; ---------- -- next -- ---------- procedure next (s : in out solution; m : in out chrom_Type; n : integer; b: out boolean) is i,max : integer; begin i := 1; s.chrom(i) := s.chrom(i) + 1; while ((i < n) and (s.chrom(i) > m(i) + 1)) loop s.chrom(i) := 1; i := i + 1; s.chrom(i) := s.chrom(i) + 1; end loop; -- If i is has reached n-1 th element, then the last unique partitiong -- has been found if (i = n) then b := false; else -- Because all the first i elements are now 1, s[i] (i + 1 th element) -- is the largest. So we update max by copying it to all the first i -- positions in m. max := s.chrom(i); if (m(i) > max) then max := m(i); end if; for j in 1 .. i-1 loop m(j) := max; end loop; b := true; end if; end next; end exact_front_computation;