------------------------------------------------------------------------------ ------------------------------------------------------------------------------ -- 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-2016, Frank Singhoff, Alain Plantec, Jerome Legrand -- -- The Cheddar project was started in 2002 by -- Frank Singhoff, Lab-STICC UMR 6285 laboratory, 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: 1249 $ -- $Date: 2014-08-28 07:02:15 +0200 (Fri, 28 Aug 2014) $ -- $Author: singhoff $ ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; with Generic_Graph; use Generic_Graph; with Tasks; use Tasks; with Task_Set; use Task_Set; with Task_Groups; use Task_Groups; with Task_Group_Set; use Task_Group_Set; with Buffers; use Buffers; with Messages; use Messages; with Dependencies; use Dependencies; with Resources; use Resources; use Resources.Resource_Accesses; with Systems; use Systems; with Processors; use Processors; with Processor_Set; use Processor_Set; with Address_Spaces; use Address_Spaces; with Address_Space_Set; use Address_Space_Set; with Caches; use Caches; with Caches; use Caches.Cache_Blocks_Table_Package; with Message_Set; use Message_Set; with Buffer_Set; use Buffer_Set; with Network_Set; use Network_Set; with Event_Analyzer_Set; use Event_Analyzer_Set; with Resource_Set; use Resource_Set; with Task_Dependencies; use Task_Dependencies; with Buffers; use Buffers; use Buffers.Buffer_Roles_Package; with Queueing_Systems; use Queueing_Systems; with convert_strings; with unbounded_strings; use unbounded_strings; with convert_unbounded_strings; with Text_IO; use Text_IO; with Systems; use Systems; with Objects; use Objects; with Parameters.extended; use Parameters.extended; with Scheduler_Interface; use Scheduler_Interface; with Ada.Finalization; with unbounded_strings; use unbounded_strings; with architecture_factory; use architecture_factory; use unbounded_strings.unbounded_string_list_package; with Unchecked_Deallocation; with sets; with Framework_Config; use Framework_Config; with Ada.Float_Text_IO; with Offsets; use Offsets; with Offsets; use Offsets.Offsets_Table_Package; with Random_Tools; use Random_Tools; with initialize_framework; use initialize_framework; with Random_Tools; use Random_Tools; with Ada.Numerics.Float_Random; package body architecture_factory is cpt : Integer; procedure initialize_cpt is begin cpt := Integer (0); end initialize_cpt; -- 0 --------= System =-------- procedure Create_Time_Triggered_Communication_System (S : in out System; number_tasks : in Integer; number_Resources : in Integer; number_Messages : in Integer; number_Dependencies : in Integer; number_Core_Units : in Integer; number_Processors : in Integer; number_Buffers : in Integer; number_Address_Spaces : in Integer) is i : Integer; Preempt : Preemptives_Type; Sched : Schedulers_Type; begin Initialize (S); initialize_cpt; Preempt := Random_Preemptivity; Sched := Restrained_Random_Scheduler; i := 0; while (i < number_Core_Units) loop Add_Core_Unit_To_System (S); i := i + 1; end loop; i := 0; while (i < number_Processors) loop Add_Mono_Core_Processor_To_System (S, Preempt, Sched); i := i + 1; end loop; i := 0; while (i < number_Address_Spaces) loop Add_Address_Space_To_System (S, get_random_element (S.Processors).name); i := i + 1; end loop; i := 0; while (i < number_Buffers) loop Add_Buffer_To_System (S); i := i + 1; end loop; i := 0; while (i < number_Messages) loop i := i + 1; end loop; Add_Multiple_Tasks_To_System (S, number_tasks, Periodic_Type); i := 0; while (i < number_Resources) loop Add_Resource_To_System (S, 2); i := i + 1; end loop; i := 0; while (i < number_Dependencies) loop Add_Time_Triggered_Communication_Dependency_To_System (S); i := i + 1; end loop; end Create_Time_Triggered_Communication_System; procedure Create_Ravenscar_System (S : in out System; number_tasks : in Integer; number_Resources : in Integer; number_Messages : in Integer; number_Dependencies : in Integer; number_Core_Units : in Integer; number_Processors : in Integer; number_Buffers : in Integer; number_Address_Spaces : in Integer) is i : Integer; Preempt : Preemptives_Type; Sched : Schedulers_Type; begin Initialize (S); initialize_cpt; Preempt := Random_Preemptivity; Sched := Restrained_Random_Scheduler; i := 0; while (i < number_Core_Units) loop Add_Core_Unit_To_System (S); i := i + 1; end loop; i := 0; while (i < number_Processors) loop Add_Mono_Core_Processor_To_System (S, Preempt, Sched); i := i + 1; end loop; i := 0; while (i < number_Address_Spaces) loop Add_Address_Space_To_System (S, get_random_element (S.Processors).name); i := i + 1; end loop; i := 0; while (i < number_Buffers) loop Add_Buffer_To_System (S); i := i + 1; end loop; i := 0; while (i < number_Messages) loop --Add_Message_To_System (S); i := i + 1; end loop; Add_Multiple_Tasks_To_System (S, number_tasks, Periodic_Type); i := 0; while (i < number_Resources) loop Add_Resource_To_System (S, 0); i := i + 1; end loop; i := 0; while (i < number_Dependencies) loop Add_Time_Triggered_Communication_Dependency_To_System (S); i := i + 1; end loop; end Create_Ravenscar_System; -- ------------------------------------------------------------------------- -------------------- -- This procedure creates X multiframes and adds frames to them. -- It first adds one frame to each at least -- Then it adds frames randomly to any multiframe -- X% of frames are added with respect to mf_period -- X% is computed according to sync_ratio (ratio of multiframes that have --the same mf_period) -- Synched multiframes have their tail frame's interarrival modified to --match mf_period -- Prec_Deps are added by going through synched multiframes. -- For each frame, a Prec_Dep is added with a probability of prec_prob -- The Prec_Dep is from the current multiframe's frame to the next --multiframe's random frame ---------------------------------------------------------------------------- -------------------- procedure Create_MF_System (S : in out System; number_groups : in Integer; number_frames : in Integer; number_resources : in Integer; number_resource_usages : in Integer; number_core_units_per_processor : in Integer; number_processors : in Integer; number_address_spaces : in Integer; Sched : in Schedulers_Type; mf_period : in Integer := 0; sync_ratio : in Double := 0.0; number_precedences : in Integer := 0) is Preempt : Preemptives_Type; i : Integer; begin Initialize (S); initialize_cpt; Preempt := preemptive; -- ***** Processors generation ***** Add_Multiple_Processors_To_System (S, number_processors, number_core_units_per_processor, Sched, Preempt); -- ***** Address_Spaces generation ***** Add_Multiple_Address_Spaces_Consistently_To_System (S, number_processors, number_address_spaces); -- ***** Task Groups generation ***** Add_Multiple_Task_Groups_To_System (S, number_groups, Multiframe_Type); -- ***** Tasks generation ***** Add_Multiple_Frame_Tasks_To_System (S, number_frames, mf_period, sync_ratio); -- ***** Resources generation ***** i := 0; while (i < number_resources) loop Add_Resource_To_System (S, number_resource_usages); i := i + 1; end loop; -- ***** Precedence Dependencies generation ***** Add_Multiple_MF_Precedence_Dependencies_To_System (S, number_precedences, number_groups, sync_ratio); end Create_MF_System; -------------------------------------------- -- Generate_A_Customized_Ravenscar_System -- -------------------------------------------- procedure Generate_A_Customized_Ravenscar_System (my_system : in out System; N : in Integer; -- number of tasks Target_cpu_utilization : in Float; -- desired cpu utilization Current_cpu_utilization : out Float; -- cpu utilization of the generated system N_diff_periods : in Integer; -- number of maximum different periods N_resources : in Integer; -- number of resources rsf : in Float; -- resource sharing factor csr : in Float; -- critical section ratio A_sched_policy : in Policies) is use Ada.Float_Text_IO; My_resources : Resources_set; my_tasks : Tasks_Set; suited_current_cpu_utilization : boolean := false; schedulable : boolean := false; Variation_percentage : float := 0.09; -- Tolerated percentage of variation from the target cpu_utilization begin while not suited_current_cpu_utilization loop suited_current_cpu_utilization := false; Current_cpu_utilization := 0.0; Create_Independant_Periodic_TaskSet_System (S => my_system, Current_cpu_utilization => Current_cpu_utilization, N_Tasks => N, Target_cpu_utilization => Target_cpu_utilization, D_Min => 1.0, D_Max => 1.0, Is_synchronous => true, N_Different_Periods => N_diff_periods, --10, A_sched_policy => A_sched_policy); Add_Resource_Set_To_System (S => my_system, N_Resources => N_resources, Resource_sharing_factor => rsf, critical_section_ratio => csr); if ABS(Target_cpu_utilization - Current_cpu_utilization) <= Variation_percentage then suited_current_cpu_utilization := true; end if; end loop; end Generate_A_Customized_Ravenscar_System; ------------------------------------------------ -- Create_Independant_Periodic_TaskSet_System -- ------------------------------------------------ procedure Create_Independant_Periodic_TaskSet_System (S : in out System; Current_cpu_utilization : in out Float; N_Tasks : in Integer; Target_cpu_utilization : in Float; D_Min : in Float := 1.0; D_Max : in Float := 1.0; Is_synchronous : in Boolean := true; N_Different_Periods : in Integer; A_sched_policy : in Policies) is use Ada.Numerics.Float_Random ; A_Factor : Integer; U_values : Random_Tools.Float_Array (0 .. N_Tasks-1); T_values : Random_Tools.Integer_Array (1 .. N_Tasks); A_capacity : natural := 0; A_period : natural := 0; A_deadline : natural := 0; A_start_time : natural := 0; A_random_deadline : float; oMin, oMax : float; A_random_offset : float; My_resources : Resources_set; my_tasks : Tasks_Set; A_Task_priority : integer; G : Ada.Numerics.Float_Random.Generator; begin if A_sched_policy = SCHED_FIFO then A_Task_priority := 1; else A_Task_priority := 0; end if; A_Factor := 1;--N_Tasks; Reset (G); U_values := Gen_UUniFast (N_Tasks, Target_cpu_utilization); T_values := Generate_Period_set_with_Limited_HyperPeriod (N_Tasks, N_Different_Periods); Initialize (my_tasks); for i in 1 .. N_Tasks loop A_period := Natural (T_values(i) * A_Factor); -- A_factor inflates the periods to avoid too much execution times -- equal to zero due to integer rounding A_capacity := Integer (Float'Rounding (Float(A_period) * U_values(i-1))); if A_capacity = 0 then A_capacity := 1; end if; A_random_deadline := D_Min + random(G) * (D_Max - D_Min); while (A_random_deadline > D_Max) or (A_random_deadline < D_Min) loop A_random_deadline := D_Min + random(G) * (D_Max - D_Min); end loop; A_deadline := Integer (Float'Rounding (Float(A_period - A_capacity) * A_random_deadline)) + A_capacity; oMin := 0.0; oMax := float(A_period); if (not Is_synchronous) then A_random_offset := oMin + random(G) * (oMax - oMin); while (A_random_offset > oMax) or (A_random_offset < oMin) loop A_random_offset := oMin + random(G) * (oMax - oMin); end loop; A_start_time := Integer (Float'Rounding (A_random_offset)); else A_start_time := 0; end if; Current_cpu_utilization := Current_cpu_utilization + Float(A_capacity) / Float(A_period); 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 => A_start_Time, Capacity => A_capacity, Period => A_period, Deadline => A_deadline, Jitter => 0, Blocking_Time => 0, Priority => A_Task_priority, Criticality => 0, Policy => A_sched_policy); end loop; S.Tasks := my_tasks; end Create_Independant_Periodic_TaskSet_System; -- 8 --------= Tasks_Set =-------- procedure Add_Task_Deadline_equals_period_To_System (S : in out System; Name : in Unbounded_String; Cpu_Name : in Unbounded_String; Address_Space_Name : in Unbounded_String; Task_Type : in Tasks_Type) is i : Integer; begin i := Random_Integer (64); Add_Task (S.Tasks, Name, Cpu_Name, Address_Space_Name, Task_Type, 0, 1, i, i, 0, 0, (cpt mod 230) + 10, 1, Sched_Fifo); end Add_Task_Deadline_equals_period_To_System; procedure Add_Task_Deadline_larger_than_period_To_System (S : in out System; Name : in Unbounded_String; Cpu_Name : in Unbounded_String; Address_Space_Name : in Unbounded_String; Task_Type : in Tasks_Type) is begin Add_Task (S.Tasks, Name, Cpu_Name, Address_Space_Name, Task_Type, 0, 1, cpt, cpt + 1, 0, 0, (cpt mod 230) + 10, 1, Sched_Fifo); cpt := cpt + 1; end Add_Task_Deadline_larger_than_period_To_System; procedure Add_Task_Deadline_smaller_than_period_To_System (S : in out System; Name : in Unbounded_String; Cpu_Name : in Unbounded_String; Address_Space_Name : in Unbounded_String; Task_Type : in Tasks_Type) is begin Add_Task (S.Tasks, Name, Cpu_Name, Address_Space_Name, Task_Type, 0, 1, cpt + 1, cpt, 0, 0, (cpt mod 230) + 10, 1, Sched_Fifo); cpt := cpt + 1; end Add_Task_Deadline_smaller_than_period_To_System; procedure Add_Aperiodic_Task_To_System (S : in out System; Name : in Unbounded_String; Cpu_Name : in Unbounded_String; Address_Space_Name : in Unbounded_String) is begin Add_Task (S.Tasks, Name, Cpu_Name, Address_Space_Name, Aperiodic_Type, 0, 1, 0, cpt, 0, 0, (cpt mod 230) + 10, 1, Sched_Fifo); end Add_Aperiodic_Task_To_System; procedure Add_Parametic_Task_To_System (S : in out System; Name : in Unbounded_String; Cpu_Name : in Unbounded_String; Address_Space_Name : in Unbounded_String) is begin Add_Task (S.Tasks, Name, Cpu_Name, Address_Space_Name, Aperiodic_Type, 0, 1, 0, cpt, 0, 0, (cpt mod 230) + 10, 1, Sched_Fifo); end Add_Parametic_Task_To_System; procedure Add_Poisson_Task_To_System (S : in out System; Name : in Unbounded_String; Cpu_Name : in Unbounded_String; Address_Space_Name : in Unbounded_String) is begin Add_Task (S.Tasks, Name, Cpu_Name, Address_Space_Name, Poisson_Type, 0, 1, 0, cpt, 0, 0, (cpt mod 230) + 10, 1, Sched_Fifo); end Add_Poisson_Task_To_System; procedure Add_Periodic_Task_To_System (S : in out System; Name : in Unbounded_String; Cpu_Name : in Unbounded_String; Address_Space_Name : in Unbounded_String) is i : Integer; begin i := Random_Integer (3); case i is when 0 => Add_Task_Deadline_smaller_than_period_To_System (S, Name, Cpu_Name, Address_Space_Name, Periodic_Type); when 1 => Add_Task_Deadline_larger_than_period_To_System (S, Name, Cpu_Name, Address_Space_Name, Periodic_Type); when others => Add_Task_Deadline_equals_period_To_System (S, Name, Cpu_Name, Address_Space_Name, Periodic_Type); end case; end Add_Periodic_Task_To_System; procedure Add_Frame_Task_To_System (S : in out System; Name : in Unbounded_String; Cpu_Name : in Unbounded_String; Address_Space_Name : in Unbounded_String) is i : Integer; begin -- TODO MF logic to respect i := Random_Integer (3); case i is when 0 => Add_Task_Deadline_smaller_than_period_To_System (S, Name, Cpu_Name, Address_Space_Name, Frame_Task_Type); when 1 => Add_Task_Deadline_larger_than_period_To_System (S, Name, Cpu_Name, Address_Space_Name, Frame_Task_Type); when others => Add_Task_Deadline_equals_period_To_System (S, Name, Cpu_Name, Address_Space_Name, Frame_Task_Type); end case; end Add_Frame_Task_To_System; procedure Add_Multiple_Tasks_To_System (S : in out System; N : Integer; Task_Type : in Tasks_Type) is i : Integer; begin i := 0; while (i < N) loop case Task_Type is when Periodic_Type => Add_Periodic_Task_To_System (S, suppress_space (To_Unbounded_String ("Task" & cpt'Img)), get_random_element (S.Processors).name, get_random_element (S.Address_Spaces).name); when Aperiodic_Type => Add_Aperiodic_Task_To_System (S, suppress_space (To_Unbounded_String ("Task" & cpt'Img)), get_random_element (S.Processors).name, get_random_element (S.Address_Spaces).name); --when Sporadic_Type => Add_Sporadic_Task_To_System --(S,suppress_space(to_unbounded_string("Task" --&cpt'IMG)),get_random_element(S.Processors).Name,get_random_eleme --nt(S.Address_spaces).Name); --when Poisson_Type => Add_Sporadic_Task_To_System --(S,suppress_space(to_unbounded_string("Task" --&cpt'IMG)),get_random_element(S.Processors).Name,get_random_eleme --nt(S.Address_spaces).Name); when Frame_Task_Type => Add_Frame_Task_To_System (S, suppress_space (To_Unbounded_String ("Task" & cpt'Img)), get_random_element (S.Processors).name, get_random_element (S.Address_Spaces).name); when others => Add_Periodic_Task_To_System (S, suppress_space (To_Unbounded_String ("Task" & cpt'Img)), get_random_element (S.Processors).name, get_random_element (S.Address_Spaces).name); end case; --Add_Task_Deadline_equals_period_To_System --(S,suppress_space(to_unbounded_string("Task" --&cpt'IMG)),get_random_element(S.Processors).Name,get_random_element( --S.Address_spaces).Name,Task_type); i := i + 1; cpt := cpt + 1; end loop; end Add_Multiple_Tasks_To_System; procedure Add_Multiple_Frame_Tasks_To_System (S : in out System; number_frames : in Integer; mf_period : in Integer; sync_ratio : in Double) is use Generic_Task_Group_Set; use Generic_Task_List_Package; number_groups : constant Task_Groups_Range := get_number_of_elements (S.Task_Groups); sync_number : Integer; remaining_period : Integer; interarrival : Integer; remaining_frames : Integer; group_tasks_number : Natural; j : Task_Groups_Range; A_Task_Group : Generic_Task_Group_Ptr; A_Multiframe : Multiframe_Task_Group_Ptr; Tail_Frame_Task : Frame_Task_Ptr; An_Address_Space : Address_Space_Ptr; Address_Space_Name : Unbounded_String; Cpu_Name : Unbounded_String; begin -- Sync_Number: The first "sync_number" multiframes have the same --mf_period sync_number := Integer (Double (number_groups) * sync_ratio); -- TODO: --Round --up or --down? for i in 0 .. (number_groups - 1) loop get_element_number (S.Task_Groups, A_Task_Group, i); if (is_empty (A_Task_Group.task_list)) then -- First frame so a random interarrival no matter the sync_number interarrival := Random_Integer (mf_period / 2) + 1; -- Get random addr and cpu An_Address_Space := get_random_element (S.Address_Spaces); Address_Space_Name := An_Address_Space.name; Cpu_Name := An_Address_Space.cpu_name; end if; group_tasks_number := get_number_of_elements (A_Task_Group.task_list) + 1; Add_Task (S.Tasks, S.Task_Groups, A_Task_Group.name, suppress_space (A_Task_Group.name & To_Unbounded_String ("_") & group_tasks_number'Img), -- Task_Name Cpu_Name, Address_Space_Name, Frame_Task_Type, 0, -- start_time Random_Integer (mf_period / 2) + 1, -- capacity interarrival, -- period ~ interarrival 99999, -- deadline 0, 0, 1, -- priority 0, Sched_Fifo); end loop; remaining_frames := number_frames - Integer (number_groups); while (remaining_frames > 0) loop j := Task_Groups_Range (Random_Integer (Integer (number_groups))); get_element_number (S.Task_Groups, A_Task_Group, j); Tail_Frame_Task := Frame_Task_Ptr (get_tail (A_Task_Group.task_list)); -- Addr and CPU must match for all frames Address_Space_Name := Tail_Frame_Task.address_space_name; Cpu_Name := Tail_Frame_Task.cpu_name; if (Integer (j) < sync_number) then -- Compute allowed random value of interarrival (in interval --between last interarrival and mf_period) remaining_period := mf_period - Tail_Frame_Task.period; if (remaining_period > 0) then interarrival := Random_Integer (remaining_period) + 1; else interarrival := 0; end if; else interarrival := Random_Integer (mf_period / 2) + 1; end if; group_tasks_number := get_number_of_elements (A_Task_Group.task_list) + 1; Add_Task (S.Tasks, S.Task_Groups, A_Task_Group.name, suppress_space (A_Task_Group.name & To_Unbounded_String ("_") & group_tasks_number'Img), -- Task_Name Cpu_Name, Address_Space_Name, Frame_Task_Type, 0, -- start_time Random_Integer (mf_period / 2) + 1, -- capacity interarrival, -- period ~ interarrival 99999, -- deadline 0, 0, 1, -- priority 0, Sched_Fifo); remaining_frames := remaining_frames - 1; end loop; -- Modify synched multiframes' tail_task interarrival, so the --multiframe's period matches mf_period for i in 0 .. (sync_number - 1) loop j := Task_Groups_Range (i); -- Get the multiframe get_element_number (S.Task_Groups, A_Task_Group, j); A_Multiframe := Multiframe_Task_Group_Ptr (A_Task_Group); -- Get tail task Tail_Frame_Task := Frame_Task_Ptr (get_tail (A_Task_Group.task_list)); -- Compute allowed random value of interarrival (in interval between --last interarrival and mf_period) interarrival := Tail_Frame_Task.interarrival + mf_period - Tail_Frame_Task.period; Set_Interarrival (Tail_Frame_Task, A_Multiframe, interarrival); end loop; -- Set precedence dependencies between frames of a same multiframe group Set_Multiframe_Precedences (S.Task_Groups, S.Dependencies); end Add_Multiple_Frame_Tasks_To_System; -- 9 --------= Resources_Set =-------- procedure Add_Resource_To_System (S : in out System; N_dependent_tasks : Integer) is use Generic_Task_Set; Local_Affected_Tasks : Resource_Accesses_Table; res : Critical_Section; i : Integer; item : Resource_Accesses_Range; range_end : Resource_Accesses_Range; name1 : Unbounded_String; name2 : Unbounded_String; protocol : Resources_Type; resource_priority : Integer := 10; A_Task : Generic_Task_Ptr; begin i := 1; protocol := Restrained_Random_Resource_Type; A_Task := get_random_element (S.Tasks); name1 := A_Task.name; Initialize (res); loop name2 := get_random_element (S.Tasks).name; exit when name1 /= name2 or get_number_of_elements (S.Tasks) = 1; end loop; add (Local_Affected_Tasks, name2, Copy (res).all); add (Local_Affected_Tasks, name1, Copy (res).all); initialize (Local_Affected_Tasks); for i in 1 .. (N_dependent_tasks - 2) loop -- Note: scheduler considers resource usages start at 1 instead of 0 --in a task's execution interval, -- but end at task's execution interval upper bound. I.e. shift --+1 start but keep end. res.task_begin := Random_Integer (A_Task.capacity) + 1; -- start in --[1 ; --task.capaci --ty] res.task_end := Random_Integer (res.task_begin, A_Task.capacity); -- end in [start ; task.capacity] add (Local_Affected_Tasks, get_random_element (S.Tasks).name, Copy (res).all); end loop; Add_Resource (S.Resources, suppress_space (To_Unbounded_String ("resource_" & cpt'Img)), 0, 0, 1, get_random_element (S.Processors).name, get_random_element (S.Address_Spaces).name, protocol, Local_Affected_Tasks, resource_priority, Automatic_Assignment); range_end := Search_Resource (S.Resources, suppress_space (To_Unbounded_String ("resource_" & cpt'Img))). critical_sections.nb_entries; item := 0; loop Add_One_Task_Dependency_resource (S.Dependencies, Search_Task (S.Tasks, Search_Resource (S.Resources, suppress_space (To_Unbounded_String ("resource_" & cpt'Img))). critical_sections.entries (item).item), Search_Resource (S.Resources, suppress_space (To_Unbounded_String ("resource_" & cpt'Img)))); item := item + 1; exit when item >= range_end; end loop; if (protocol = Priority_Ceiling_Protocol) or (protocol = Immediate_Priority_Ceiling_Protocol) then --Priority_Constrained_Resource_Ptr (Search_Resource -- (S.Resources, -- Suppress_Space -- (To_Unbounded_String -- ("resource_" & -- cpt'Img)))). -- ceiling_priority := 254; Generic_Resource_Ptr (Search_Resource (S.Resources, suppress_space (To_Unbounded_String ("resource_" & cpt'Img)))).priority := 254; end if; cpt := cpt + 1; end Add_Resource_To_System; procedure Add_Resource_To_System (S : in out System; Name : in Unbounded_String; N_dependent_tasks : Integer) is Local_Affected_Tasks : Resource_Accesses_Table; res : Critical_Section; i : Integer; item : Resource_Accesses_Range; range_end : Resource_Accesses_Range; name1 : Unbounded_String; name2 : Unbounded_String; resource_priority : Integer:= 10; begin i := 1; name1 := get_random_element (S.Tasks).name; loop name2 := get_random_element (S.Tasks).name; exit when name1 /= name2; end loop; for i in 1 .. N_dependent_tasks loop initialize (Local_Affected_Tasks); res.task_begin := 0; res.task_end := 1; add (Local_Affected_Tasks, get_random_element (S.Tasks).name, Copy (res).all); end loop; Add_Resource (S.Resources, Name, 0, 0, 1, get_random_element (S.Processors).name, get_random_element (S.Address_Spaces).name, Restrained_Random_Resource_Type, Local_Affected_Tasks, resource_priority, Automatic_Assignment); range_end := Search_Resource (S.Resources, suppress_space (To_Unbounded_String ("resource_" & cpt'Img))). critical_sections.nb_entries; item := 0; loop Add_One_Task_Dependency_resource (S.Dependencies, Search_Task (S.Tasks, Search_Resource (S.Resources, suppress_space (To_Unbounded_String ("resource_" & cpt'Img))). critical_sections.entries (item).item), Search_Resource (S.Resources, suppress_space (To_Unbounded_String ("resource_" & cpt'Img)))); item := item + 1; exit when item >= range_end; end loop; cpt := cpt + 1; end Add_Resource_To_System; procedure Add_Multiple_Resources_To_System (S : in out System; N : Integer) is begin null; end Add_Multiple_Resources_To_System; procedure Add_Resource_Set_To_System (S : in out System; N_Resources : in Integer; Resource_sharing_factor : in Float; critical_section_ratio : in Float := 0.0) is N_tasks : Tasks_Range := Get_Number_Of_Task_From_Processor (S.Tasks, To_Unbounded_String("processor1")); Max_accessed_tasks : integer := Integer(Float'Ceiling (Float(N_tasks) * Resource_sharing_factor)); Max_all_sc : integer := Max_accessed_tasks * N_Resources; type array_of_integer is array (1 .. 1500) of integer; --type array_of_integer is array (1 .. Max_all_sc) of integer; Affected_Tasks_tab : array_of_integer; -- Resource_tab is an array where each element represents the number of -- of critical sections per resource Resource_tab : array (1 .. N_Resources) of integer; k, h : Integer; N_critical_sections : Integer; A_task_index, N_accessed_tasks : Integer; Is_used : boolean; Critical_sections_tab : array (1 .. 1500) of critical_section; --Critical_sections_tab : array (1 .. Max_all_sc) of critical_section; Length_a_cs : Integer; cs : critical_section; critical_section_ratio_final : float; Task_capacity : natural; A_Resource_set : Resources_Set; rt : Resource_Accesses_Table; N_cs_of_a_resource : Integer; A_task_name : Unbounded_String; rnd : integer; function Find_an_element (An_array : in array_of_integer; Element : in Integer; Start_index : in Integer; Last_index : in Integer) return boolean is Is_found : boolean := false; k : integer; begin k := Start_index; while (Not Is_found) and (k <= Last_index) loop if An_array(k) = Element then Is_found := true; end if; k := k + 1; end loop; return Is_found; end Find_an_element; begin -- 2) Each resource Rj is accessed by a number of different functions -- randomly chosen from the set of functions. -- This number is randomly chosen in the range [2 , Resource_sharing_factor * N_tasks] -- k := 0; Affected_Tasks_tab (1500) := 0; for i in 1 .. N_Resources loop if Max_accessed_tasks > 2 then N_accessed_tasks := random_Integer (2 , Max_accessed_tasks); else N_accessed_tasks := 2; end if; h := k + 1; Resource_tab(i) := N_accessed_tasks; for j in 1 .. N_accessed_tasks loop Is_used := true; while Is_used loop A_task_index := random_Integer(1 , Integer(N_tasks)); Is_used := Find_an_element(Affected_Tasks_tab, A_task_index, h, k); end loop; k := k + 1; Affected_Tasks_tab(k) := A_task_index; end loop; end loop; N_critical_sections := k; -- 3) Each Task Task_i that accesses a given resource Rj, -- issues only a single request of Rj per a job -- with a critical section Length: -- • The length of each critical section CS executed by a Task Task_j , is set as follows: -- Length(CS) = Integer(Float'Ceiling(critical_section_ratio * float(capacity(Task_j))) -- If the critical section ratio = 0.0 then -- it will be chosen randomly from the set {0.1, 0.3, 0.5} -- else (i.e the critical section ratio is given by user) -- we use the given value -- -- • CS.task_begin : randomly generated in the range [1, capacity(Task_j) – Length(CS) + 1 ] -- • CS.task_end = CS.task_begin + Length(CS) – 1 -- for i in 1 .. N_critical_sections loop if critical_section_ratio = 0.0 then -- The critical section ratio is chosen -- randomly from the set {0.1, 0.3, 0.5} rnd := random_Integer(1,3); if rnd = 1 then critical_section_ratio_final := 0.1; elsif rnd = 2 then critical_section_ratio_final := 0.3; else critical_section_ratio_final := 0.5; end if; else critical_section_ratio_final := critical_section_ratio; end if; Task_capacity := Get (My_Tasks => S.Tasks, Task_Name => Suppress_Space (To_Unbounded_String ("Task" & Integer'Image(Affected_Tasks_tab(i)))), Param_Name => Capacity); Length_a_cs := Integer(Float'Ceiling(critical_section_ratio_final * Float(Task_capacity))); cs.task_begin := Natural(random_Integer(1 , Task_capacity - Length_a_cs + 1)); cs.task_end := cs.task_begin + Natural(Length_a_cs) - 1; Critical_sections_tab(i) := cs; end loop; -- Assign to each resource its critical sections -- for i in 1 .. N_resources loop N_cs_of_a_resource := Resource_tab(i); Initialize(rt); k := 0; for l in 1 .. i-1 loop k := k + Resource_tab(l); end loop; k := k + 1; for j in 1 .. N_cs_of_a_resource loop A_task_name := Suppress_Space (To_Unbounded_String ("Task" & Integer'Image(Affected_Tasks_tab(k)))); cs := Critical_sections_tab(k); -- Add the computed critical_section_j to the table of -- critical sections of the Resource_i -- add (rt, A_task_name, cs); k := k + 1; end loop; -- Add the resource Ri to the set of resources -- Add_Resource (A_Resource_set, suppress_space (To_Unbounded_String ("R" & i'Img)), 1, 0, 0, To_Unbounded_String ("processor1"), To_Unbounded_String ("addr1"), Priority_Ceiling_Protocol, rt, 0, Automatic_Assignment); end loop; -- Assign the resource set to the system -- S.Resources := A_Resource_set; end Add_Resource_Set_To_System; -- 3 --------= Messages_Set =-------- procedure Add_Message_To_System (S : in out System) is begin Add_Message (S.Messages, suppress_space (To_Unbounded_String ("message" & cpt'Img)), 1, 0, 0, 0, No_User_Defined_Parameter, 0, 0); cpt := cpt + 1; end Add_Message_To_System; procedure Add_Message_To_System (S : in out System; Name : in Unbounded_String) is begin Add_Message (S.Messages, Name, 1, 0, 0, 0, No_User_Defined_Parameter, 0, 0); cpt := cpt + 1; end Add_Message_To_System; procedure Add_Multiple_Messages_To_System (S : in out System; N : Integer) is i : Integer; begin i := 0; while (i < N) loop Add_Message_To_System (S); i := i + 1; end loop; end Add_Multiple_Messages_To_System; -- 10 --------= Dependecies =-------- procedure Add_Time_Triggered_Communication_Dependency_To_System (S : in out System) is begin Add_One_Task_Dependency_time_triggered (S.Dependencies, get_random_element (S.Tasks), get_random_element (S.Tasks), Sampled_Timing); end Add_Time_Triggered_Communication_Dependency_To_System; procedure Add_Dependency_To_System (S : in out System; Name : in Unbounded_String) is begin null; end Add_Dependency_To_System; procedure Add_Multiple_Dependencies_To_System (S : in out System; N : Integer) is begin null; end Add_Multiple_Dependencies_To_System; procedure Add_Multiple_MF_Precedence_Dependencies_To_System (S : in out System; number_precedences : in Integer; number_groups : in Integer; sync_ratio : in Double) is use Generic_Task_Group_Set; use Generic_Task_List_Package; a, b, i, sync_number, max_precs : Integer; Task_Group_A, Task_Group_B : Generic_Task_Group_Ptr; Task_A, Task_B : Generic_Task_Ptr; begin -- Sync_Number: The first "sync_number" multiframes have the same --mf_period sync_number := Integer (Double (number_groups) * sync_ratio); -- TODO: --Round --up or --down?* -- Only on group is synched if (sync_number <= 1 or number_groups = 1) then return; end if; max_precs := Get_No_Deadlocks_Precedences_Number (S.Task_Groups, sync_number); i := 0; while (i < number_precedences and i < max_precs) loop loop loop a := Random_Integer (sync_number); b := Random_Integer (sync_number); -- a := Random_Integer(sync_number - 1); -- b := Random_Integer(a, sync_number); get_element_number (S.Task_Groups, Task_Group_A, Task_Groups_Range (a)); get_element_number (S.Task_Groups, Task_Group_B, Task_Groups_Range (b)); exit when (Task_Group_A.name /= Task_Group_B.name); end loop; Task_A := get_random_element (Task_Group_A.task_list); Task_B := get_random_element (Task_Group_B.task_list); exit when (Is_Unique_Precedence_Dependency (S.Dependencies, Task_A, Task_B) and No_Precedence_Dependency_Deadlock (S.Dependencies, Task_A, Task_B)); end loop; Add_One_Task_Dependency_precedence (S.Dependencies, Search_Task (S.Tasks, Task_A.name), Search_Task (S.Tasks, Task_B.name)); i := i + 1; end loop; end Add_Multiple_MF_Precedence_Dependencies_To_System; -- 11 --------= Task_Groups_Set =-------- procedure Add_Task_Group_To_System (S : in out System; Task_Group_Type : in Task_Groups_type) is begin Add_Task_Group_To_System (S, suppress_space (To_Unbounded_String ("TaskGroup" & cpt'Img)), Task_Group_Type); cpt := cpt + 1; end Add_Task_Group_To_System; procedure Add_Task_Group_To_System (S : in out System; Name : in Unbounded_String; Task_Group_Type : in Task_Groups_type) is begin Add_Task_Group (S.Task_Groups, Name, Task_Group_Type); end Add_Task_Group_To_System; procedure Add_Multiple_Task_Groups_To_System (S : in out System; N : Integer; Task_Group_Type : in Task_Groups_type) is i : Integer; begin i := 0; while (i < N) loop case Task_Group_Type is when Multiframe_Type => Add_Task_Group_To_System (S, Multiframe_Type); when Transaction_Type => Add_Task_Group_To_System (S, Transaction_Type); when others => null; end case; i := i + 1; end loop; end Add_Multiple_Task_Groups_To_System; -- 1 --------= Core_Units_Set =-------- procedure Add_Core_Unit_To_System (S : in out System) is begin Add_core_unit (S.Core_units, suppress_space (To_Unbounded_String ("core_unit" & cpt'Img)), preemptive, 0, 0.0, 0, 0, 0, empty_string, Earliest_Deadline_First_Protocol); cpt := cpt + 1; end Add_Core_Unit_To_System; procedure Add_Core_Unit_To_System (S : in out System; Sched : in Schedulers_Type) is begin Add_core_unit (S.Core_units, suppress_space (To_Unbounded_String ("core_unit" & cpt'Img)), preemptive, 0, 1.0, 0, 0, 0, empty_string, Sched); cpt := cpt + 1; end Add_Core_Unit_To_System; procedure Add_Core_Unit_To_System (S : in out System; Name : in Unbounded_String) is begin Add_core_unit (S.Core_units, Name, preemptive, 0, 0.0, 0, 0, 0, empty_string, Earliest_Deadline_First_Protocol); cpt := cpt + 1; end Add_Core_Unit_To_System; procedure Add_Core_Unit_To_System (S : in out System; A_Multi_Cores_Processor : in Multi_Cores_Processor_Ptr; Sched : in Schedulers_Type; Preempt : in Preemptives_Type) is A_core_unit : Core_Unit_Ptr; name_core_unit : Unbounded_String; begin name_core_unit := suppress_space (To_Unbounded_String ("core_unit" & cpt'Img)); Add_core_unit (S.core_units, A_core_unit, name_core_unit, Preempt, 0, 1.0, 0, 0, 0, empty_string, Sched); -- Put_Line ("after adding core unit to system"); -- Put (Sched'Img); Add (A_Multi_Cores_Processor.all.cores, Search_core_unit (S.Core_units, name_core_unit)); -- Put(Search_core_unit (S.Core_units, name_core_unit)); -- Put_Line ("after adding core unit to processor"); cpt := cpt + 1; end Add_Core_Unit_To_System; -- 2 --------= Processors_Set =-------- procedure Add_Mono_Core_Processor_To_System (S : in out System; Preemptivity : in Preemptives_Type; Sched : in Schedulers_Type) is obj : Mono_Core_Processor_Ptr; A_core_unit : Core_Unit_Ptr; name_core_unit : Unbounded_String; begin name_core_unit := suppress_space (To_Unbounded_String ("core_unit" & cpt'Img)); Add_core_unit (S.core_units, A_core_unit, name_core_unit, Preemptivity, 0, 0.0, 0, 0, 0, empty_string, Sched); -- Put_Line ("after adding core unit to system"); -- Put (Sched'Img); obj := new Mono_Core_Processor; obj.all.core := Search_core_unit (S.Core_units, name_core_unit); -- Put(Search_core_unit (S.Core_units, name_core_unit)); -- Put_Line ("after adding core unit to processor"); cpt := cpt + 1; Add_Processor (S.Processors, suppress_space (To_Unbounded_String ("cpu" & cpt'Img)), A_core_unit); cpt := cpt + 1; end Add_Mono_Core_Processor_To_System; procedure Add_Mono_Core_Processor_To_System (S : in out System; Preemptivity : in Preemptives_Type; Sched : in Schedulers_Type; Core : Core_Unit_Ptr) is obj : Mono_Core_Processor_Ptr; obj2 : Core_Unit_Ptr; begin obj := new Mono_Core_Processor; obj.all.core := Core; cpt := cpt + 1; Add_core_unit (S.Core_units, obj2, suppress_space (To_Unbounded_String ("core" & cpt'Img)), Preemptivity, 0, 0.0, 1, 1, 0, empty_string, Sched, empty_string); Add_Processor (S.Processors, Generic_Processor_Ptr (obj), suppress_space (To_Unbounded_String ("core" & cpt'Img)), obj2); cpt := cpt + 1; end Add_Mono_Core_Processor_To_System; procedure Add_Mono_Core_Processor_To_System (S : in out System; Name : in Unbounded_String; Preemptivity : in Preemptives_Type; Sched : in Schedulers_Type) is obj : Mono_Core_Processor_Ptr; begin Add_core_unit (S.Core_units, suppress_space (To_Unbounded_String ("core_unit" & cpt'Img)), preemptive, 0, 0.0, 0, 0, 0, empty_string, Sched); cpt := cpt + 1; Add_Processor (S.Processors, Generic_Processor_Ptr (obj), Name, Search_core_unit (S.Core_units, suppress_space (To_Unbounded_String ("core_unit" & cpt'Img)))); end Add_Mono_Core_Processor_To_System; procedure Add_Multiple_Mono_Core_Processors_To_System (S : in out System; N : Integer) is i : Integer; begin i := 0; while (i < N) loop Add_Mono_Core_Processor_To_System (S, To_Unbounded_String ("cpu" & i'Img), Random_Preemptivity, Random_Scheduler); i := i + 1; end loop; end Add_Multiple_Mono_Core_Processors_To_System; procedure Add_Multi_Cores_Processor_To_System (S : in out System; Number_Core_Units : in Integer; Preemptivity : in Preemptives_Type; Sched : in Schedulers_Type) is A_Core_Unit : Core_Unit_Ptr; Name_Core_Unit : Unbounded_String; A_Core_Units_Table : Core_Units_Table; i : Integer; begin if (Number_Core_Units > 1) then i := 0; while (i < Number_Core_Units) loop Name_Core_Unit := suppress_space (To_Unbounded_String ("core_unit_" & cpt'Img)); Add_core_unit (S.Core_units, A_Core_Unit, Name_Core_Unit, Preemptivity, 0, 1.0, 0, 0, 0, empty_string, Sched); Add (A_Core_Units_Table, A_Core_Unit); cpt := cpt + 1; i := i + 1; end loop; end if; Add_Processor (S.Processors, To_Unbounded_String ("cpu" & cpt'Img), A_Core_Units_Table); cpt := cpt + 1; end Add_Multi_Cores_Processor_To_System; procedure Add_Multiple_Processors_To_System (S : in out System; Number_Processors : in Integer; Number_Core_Units_Per_Processor : in Integer; Sched : in Schedulers_Type; Preempt : in Preemptives_Type) is i : Integer; begin if (Number_Core_Units_Per_Processor = 1) then -- Only monocores i := 0; while (i < Number_Processors) loop Add_Mono_Core_Processor_To_System (S, Preempt, Sched); i := i + 1; end loop; else i := 0; while (i < Number_Processors) loop Add_Multi_Cores_Processor_To_System (S, Number_Core_Units_Per_Processor, Preempt, Sched); i := i + 1; end loop; end if; end Add_Multiple_Processors_To_System; -- 7 --------= Buffers_Set =-------- procedure Add_Buffer_To_System (S : in out System) is Addr_Name : Unbounded_String; begin Addr_Name := get_random_element (S.Address_Spaces).name; Add_Buffer_To_System (S, Search_Address_Space (S.Address_Spaces, Addr_Name).cpu_name, Addr_Name); end Add_Buffer_To_System; procedure Add_Buffer_To_System (S : in out System; Cpu_Name : in Unbounded_String; Address_Space_Name : in Unbounded_String) is Roles : Buffer_Roles_Table; begin initialize (Roles); Add_Buffer (S.Buffers, suppress_space (To_Unbounded_String ("buffer" & cpt'Img)), 5, Cpu_Name, Address_Space_Name, Qs_Pp1, Roles); cpt := cpt + 1; end Add_Buffer_To_System; procedure Add_Buffer_To_System (S : in out System; Name : in Unbounded_String; Cpu_Name : in Unbounded_String; Address_Space_Name : in Unbounded_String) is Roles : Buffer_Roles_Table; begin initialize (Roles); Add_Buffer (S.Buffers, Name, 1, Cpu_Name, Address_Space_Name, Qs_Pp1, Roles); cpt := cpt + 1; end Add_Buffer_To_System; procedure Add_Multiple_Buffers_To_System (S : in out System; N : Integer) is i : Integer; begin i := 0; while (i < N) loop Add_Buffer_To_System (S); i := i + 1; end loop; end Add_Multiple_Buffers_To_System; -- 4 --------= Networks_Set =-------- -- 5 --------= Event_Analyzers_Set =-------- -- 6 --------= Address_Spaces_Set =-------- procedure Add_Address_Space_To_System (S : in out System; cpu_name : Unbounded_String) is begin Add_Address_Space (S.Address_Spaces, suppress_space (To_Unbounded_String ("addr" & cpt'Img)), cpu_name, 0, 0, 0, 0); cpt := cpt + 1; end Add_Address_Space_To_System; procedure Add_Address_Space_To_System (S : in out System; Name : in Unbounded_String; cpu_name : Unbounded_String) is begin Add_Address_Space (S.Address_Spaces, Name, cpu_name, 0, 0, 0, 0); cpt := cpt + 1; end Add_Address_Space_To_System; procedure Add_Multiple_Address_Spaces_To_System (S : in out System; N : Integer) is i : Integer; begin i := 0; while (i < N) loop Add_Address_Space_To_System (S, get_random_element (S.Processors).name); i := i + 1; end loop; end Add_Multiple_Address_Spaces_To_System; procedure Add_Multiple_Address_Spaces_Consistently_To_System (S : in out System; Number_Processors : in Integer; Number_Address_Spaces : in Integer) is Processor_Iterator : Processors_Iterator; A_Processor : Generic_Processor_Ptr; address_spaces_left : Integer; begin -- Add at least an ADDR to each CPU reset_iterator (S.Processors, Processor_Iterator); loop current_element (S.Processors, A_Processor, Processor_Iterator); Add_Address_Space_To_System (S, A_Processor.name); exit when is_last_element (S.Processors, Processor_Iterator); next_element (S.Processors, Processor_Iterator); end loop; -- Fill remaining ADDRs randomly if there are more ADDRs than CPUs address_spaces_left := Number_Address_Spaces - Number_Processors; while (address_spaces_left > 0) loop Add_Address_Space_To_System (S, get_random_element (S.Processors).name); address_spaces_left := address_spaces_left - 1; end loop; end Add_Multiple_Address_Spaces_Consistently_To_System; -- X --------= Random Functionnalities =-------- function Random_Preemptivity return Preemptives_Type is type preempt_range is range 0 .. 1; package rand is new Ada.Numerics.Discrete_Random (preempt_range); use rand; P : preempt_range; G : Generator; begin Reset (G); P := Random (G); case P is when preempt_range (0) => return preemptive; when others => return not_preemptive; end case; end Random_Preemptivity; function Random_Scheduler return Schedulers_Type is type sched_range is range 0 .. 22; package rand is new Ada.Numerics.Discrete_Random (sched_range); use rand; P : sched_range; G : Generator; begin Reset (G); P := Random (G); case P is when sched_range (0) => return Compiled_User_Defined_Protocol; when sched_range (1) => return Automata_User_Defined_Protocol; when sched_range (2) => return Pipeline_User_Defined_Protocol; when sched_range (3) => return User_Defined_Protocol; when sched_range (4) => return Earliest_Deadline_First_Protocol; when sched_range (5) => return Least_Laxity_First_Protocol; when sched_range (6) => return Rate_Monotonic_Protocol; when sched_range (7) => return Deadline_Monotonic_Protocol; when sched_range (8) => return Round_Robin_Protocol; when sched_range (9) => return Time_Sharing_Based_On_Wait_Time_Protocol; when sched_range (10) => return Posix_1003_Highest_Priority_First_Protocol; when sched_range (11) => return D_Over_Protocol; when sched_range (12) => return Maximum_Urgency_First_Based_On_Laxity_Protocol; when sched_range (13) => return Maximum_Urgency_First_Based_On_Deadline_Protocol; when sched_range (14) => return Time_Sharing_Based_On_Cpu_Usage_Protocol; when sched_range (15) => return No_Scheduling_Protocol; when sched_range (16) => return Hierarchical_Cyclic_Protocol; when sched_range (17) => return Hierarchical_Round_Robin_Protocol; when sched_range (18) => return Hierarchical_Fixed_Priority_Protocol; when sched_range (19) => return Hierarchical_Polling_Aperiodic_Server_Protocol; when sched_range (20) => return Hierarchical_Priority_Exchange_Aperiodic_Server_Protocol; when sched_range (21) => return Hierarchical_Sporadic_Aperiodic_Server_Protocol; when others => return Hierarchical_Deferrable_Aperiodic_Server_Protocol; end case; end Random_Scheduler; function Restrained_Random_Scheduler return Schedulers_Type is type sched_range is range 0 .. 3; package rand is new Ada.Numerics.Discrete_Random (sched_range); use rand; P : sched_range; G : Generator; begin Reset (G); P := Random (G); case P is when sched_range (0) => return Earliest_Deadline_First_Protocol; when sched_range (1) => return Rate_Monotonic_Protocol; when sched_range (2) => return Deadline_Monotonic_Protocol; when others => return Posix_1003_Highest_Priority_First_Protocol; end case; end Restrained_Random_Scheduler; function Random_Dependency_Type return Dependency_Type is type depend_range is range 0 .. 4; package rand is new Ada.Numerics.Discrete_Random (depend_range); use rand; P : depend_range; G : Generator; begin Reset (G); P := Random (G); case P is when depend_range (0) => return Precedence_Dependency; when depend_range (1) => return Queueing_Buffer_Dependency; when depend_range (2) => return asynchronous_Communication_Dependency; when depend_range (3) => return Time_Triggered_Communication_Dependency; when others => return Resource_Dependency; end case; end Random_Dependency_Type; function Random_Resource_Type return Resources_Type is type Resource_range is range 0 .. 3; package rand is new Ada.Numerics.Discrete_Random (Resource_range); use rand; P : Resource_range; G : Generator; begin Reset (G); P := Random (G); case P is when Resource_range (0) => return No_Protocol; when Resource_range (1) => return Priority_Ceiling_Protocol; when Resource_range (2) => return Priority_Inheritance_Protocol; when others => return Immediate_Priority_Ceiling_Protocol; end case; end Random_Resource_Type; function Restrained_Random_Resource_Type return Resources_Type is use Rand_Res; P : Resource_range; G : Generator; begin Reset (G_Res); P := Random (G_Res); case P is when Resource_range (0) => return Priority_Ceiling_Protocol; when Resource_range (1) => return Priority_Inheritance_Protocol; when others => return Immediate_Priority_Ceiling_Protocol; end case; end Restrained_Random_Resource_Type; function Random_Task_Type return Tasks_Type is type Task_range is range 0 .. 4; package rand is new Ada.Numerics.Discrete_Random (Task_range); use rand; P : Task_range; G : Generator; begin Reset (G); P := Random (G); case P is when Task_range (0) => return Periodic_Type; when Task_range (1) => return Aperiodic_Type; when Task_range (2) => return Sporadic_Type; when Task_range (3) => return Poisson_Type; when others => return Parametric_Type; end case; end Random_Task_Type; function Random_Integer (n : Integer) return Integer is use Rand_Int; P : Int_Range; begin P := Random (G_Int); return Integer (P) mod n; end Random_Integer; function Random_Integer (n1 : Integer; n2 : Integer) return Integer is use Rand_Int; n : Integer; P : Int_Range; begin if (n1 = n2) then return n1; end if; P := Random (G_Int); if (n1 > n2) then n := n1 - n2; return (Integer (P) mod n) + n2; end if; n := n2 - n1; return (Integer (P) mod n) + n1; end Random_Integer; procedure compliant_time_triggered_communication (sys : out System) is a_core : Core_Unit_Ptr; a_core_unit_table : Core_Units_Table; begin Initialize (sys); Add_core_unit (sys.Core_units, a_core, To_Unbounded_String ("core1"), preemptive, 0, 1.0, 101, 102, 103, To_Unbounded_String (""), Rate_Monotonic_Protocol); Add (a_core_unit_table, a_core); Add_Processor (sys.Processors, To_Unbounded_String ("processor1"), a_core_unit_table); Add_Address_Space (sys.Address_Spaces, To_Unbounded_String ("addr1"), To_Unbounded_String ("processor1"), 0, 0, 0, 0); Add_Task (sys.Tasks, To_Unbounded_String ("T1"), To_Unbounded_String ("processor1"), To_Unbounded_String ("addr1"), Periodic_Type, 0, 2, 4, 4, 0, 10, 1, 0, Sched_Fifo); Add_Task (sys.Tasks, To_Unbounded_String ("T2"), To_Unbounded_String ("processor1"), To_Unbounded_String ("addr1"), Periodic_Type, 0, 3, 5, 5, 0, 10, 2, 0, Sched_Fifo); Add_Task (sys.Tasks, To_Unbounded_String ("T3"), To_Unbounded_String ("processor1"), To_Unbounded_String ("addr1"), Periodic_Type, 0, 7, 20, 20, 0, 10, 3, 0, Sched_Fifo); Add_One_Task_Dependency_time_triggered (sys.Dependencies, Search_Task (sys.Tasks, To_Unbounded_String ("T1")), Search_Task (sys.Tasks, To_Unbounded_String ("T2")), Sampled_Timing); Add_One_Task_Dependency_time_triggered (sys.Dependencies, Search_Task (sys.Tasks, To_Unbounded_String ("T2")), Search_Task (sys.Tasks, To_Unbounded_String ("T3")), Sampled_Timing); end compliant_time_triggered_communication; procedure uncompliant_time_triggered_communication (sys : out System) is a_core : Core_Unit_Ptr; a_core_unit_table : Core_Units_Table; begin Initialize (sys); Add_core_unit (sys.Core_units, a_core, To_Unbounded_String ("core1"), preemptive, 0, 1.0, 101, 102, 103, To_Unbounded_String (""), Rate_Monotonic_Protocol); Add (a_core_unit_table, a_core); Add_Processor (sys.Processors, To_Unbounded_String ("processor1"), a_core_unit_table); Add_Address_Space (sys.Address_Spaces, To_Unbounded_String ("addr1"), To_Unbounded_String ("processor1"), 0, 0, 0, 0); Add_Task (sys.Tasks, To_Unbounded_String ("T1"), To_Unbounded_String ("processor1"), To_Unbounded_String ("addr1"), Sporadic_Type, 0, 2, 4, 4, 0, 10, 1, 0, Sched_Fifo); Add_Task (sys.Tasks, To_Unbounded_String ("T2"), To_Unbounded_String ("processor1"), To_Unbounded_String ("addr1"), Periodic_Type, 0, 3, 5, 5, 0, 10, 2, 0, Sched_Fifo); Add_Task (sys.Tasks, To_Unbounded_String ("T3"), To_Unbounded_String ("processor1"), To_Unbounded_String ("addr1"), Periodic_Type, 0, 7, 20, 20, 0, 10, 3, 0, Sched_Fifo); Add_One_Task_Dependency_time_triggered (sys.Dependencies, Search_Task (sys.Tasks, To_Unbounded_String ("T1")), Search_Task (sys.Tasks, To_Unbounded_String ("T2")), Sampled_Timing); Add_One_Task_Dependency_time_triggered (sys.Dependencies, Search_Task (sys.Tasks, To_Unbounded_String ("T2")), Search_Task (sys.Tasks, To_Unbounded_String ("T3")), Sampled_Timing); end uncompliant_time_triggered_communication; procedure compliant_unplugged (sys : out System) is a_core : Core_Unit_Ptr; a_core_unit_table : Core_Units_Table; begin Initialize (sys); Add_core_unit (sys.Core_units, a_core, To_Unbounded_String ("core1"), preemptive, 0, 1.0, 101, 102, 103, To_Unbounded_String (""), Earliest_Deadline_First_Protocol); Add (a_core_unit_table, a_core); Add_Processor (sys.Processors, To_Unbounded_String ("processor1"), a_core_unit_table); Add_Address_Space (sys.Address_Spaces, To_Unbounded_String ("addr1"), To_Unbounded_String ("processor1"), 0, 0, 0, 0); Add_Task (sys.Tasks, To_Unbounded_String ("T1"), To_Unbounded_String ("processor1"), To_Unbounded_String ("addr1"), Periodic_Type, 0, 2, 4, 4, 0, 10, 1, 0, Sched_Fifo); Add_Task (sys.Tasks, To_Unbounded_String ("T2"), To_Unbounded_String ("processor1"), To_Unbounded_String ("addr1"), Periodic_Type, 0, 3, 5, 5, 0, 10, 2, 0, Sched_Fifo); Add_Task (sys.Tasks, To_Unbounded_String ("T3"), To_Unbounded_String ("processor1"), To_Unbounded_String ("addr1"), Periodic_Type, 0, 7, 20, 20, 0, 10, 3, 0, Sched_Fifo); end compliant_unplugged; procedure uncompliant_unplugged (sys : out System) is a_core : Core_Unit_Ptr; a_core_unit_table : Core_Units_Table; begin Initialize (sys); Add_core_unit (sys.Core_units, a_core, To_Unbounded_String ("core1"), preemptive, 0, 1.0, 101, 102, 103, To_Unbounded_String (""), Earliest_Deadline_First_Protocol); Add (a_core_unit_table, a_core); Add_Processor (sys.Processors, To_Unbounded_String ("processor1"), a_core); Add_Address_Space (sys.Address_Spaces, To_Unbounded_String ("addr1"), To_Unbounded_String ("processor1"), 0, 0, 0, 0); Add_Task (sys.Tasks, To_Unbounded_String ("T1"), To_Unbounded_String ("processor1"), To_Unbounded_String ("addr1"), Periodic_Type, 0, 2, 4, 4, 0, 10, 1, 0, Sched_Fifo); Add_Task (sys.Tasks, To_Unbounded_String ("T2"), To_Unbounded_String ("processor1"), To_Unbounded_String ("addr1"), Periodic_Type, 0, 3, 5, 5, 0, 10, 2, 0, Sched_Fifo); Add_Task (sys.Tasks, To_Unbounded_String ("T3"), To_Unbounded_String ("processor1"), To_Unbounded_String ("addr1"), Periodic_Type, 0, 7, 20, 20, 0, 10, 3, 0, Sched_Fifo); Add_Task (sys.Tasks, To_Unbounded_String ("A"), To_Unbounded_String ("processor1"), To_Unbounded_String ("addr1"), Aperiodic_Type, 4, 3, 0, 20, 0, 0, 3, 0, Sched_Fifo); end uncompliant_unplugged; procedure compliant_ravenscar (sys : out System) is a_core : Core_Unit_Ptr; a_core_unit_table : Core_Units_Table; rt : Resource_Accesses_Table; r : Critical_Section; item : Resource_Accesses_Range; range_end : Resource_Accesses_Range; re_pr1 : Integer:= 10; -- for resource priority begin Initialize (sys); Add_core_unit (sys.Core_units, a_core, To_Unbounded_String ("core1"), preemptive, 0, 1.0, 101, 102, 103, To_Unbounded_String (""), Posix_1003_Highest_Priority_First_Protocol); Add (a_core_unit_table, a_core); Add_Processor (sys.Processors, To_Unbounded_String ("processor1"), a_core_unit_table); Add_Address_Space (sys.Address_Spaces, To_Unbounded_String ("addr1"), To_Unbounded_String ("processor1"), 0, 0, 0, 0); Add_Task (sys.Tasks, To_Unbounded_String ("T1"), To_Unbounded_String ("processor1"), To_Unbounded_String ("addr1"), Periodic_Type, 0, 2, 4, 4, 0, 10, 1, 0, Sched_Fifo); Add_Task (sys.Tasks, To_Unbounded_String ("T2"), To_Unbounded_String ("processor1"), To_Unbounded_String ("addr1"), Periodic_Type, 0, 3, 5, 5, 0, 10, 2, 0, Sched_Fifo); Add_Task (sys.Tasks, To_Unbounded_String ("T3"), To_Unbounded_String ("processor1"), To_Unbounded_String ("addr1"), Periodic_Type, 0, 7, 20, 20, 0, 10, 3, 0, Sched_Fifo); r.task_begin := 1; r.task_end := 1; add (rt, To_Unbounded_String ("T1"), r); add (rt, To_Unbounded_String ("T2"), r); Add_Resource (sys.Resources, To_Unbounded_String ("R1"), 1, 0, 0, To_Unbounded_String ("processor1"), To_Unbounded_String ("addr1"), Priority_Inheritance_Protocol, rt, re_pr1, Automatic_Assignment); range_end := Search_Resource (sys.Resources, suppress_space (To_Unbounded_String ("R1"))).critical_sections. nb_entries; item := 0; loop Add_One_Task_Dependency_resource (sys.Dependencies, Search_Task (sys.Tasks, Search_Resource (sys.Resources, suppress_space (To_Unbounded_String ("R1"))). critical_sections.entries (item).item), Search_Resource (sys.Resources, suppress_space (To_Unbounded_String ("R1")))); item := item + 1; exit when item >= range_end; end loop; end compliant_ravenscar; procedure uncompliant_ravenscar (sys : out System) is a_core : Core_Unit_Ptr; a_core_unit_table : Core_Units_Table; rt : Resource_Accesses_Table; r : Critical_Section; item : Resource_Accesses_Range; range_end : Resource_Accesses_Range; --re_pr1 : integer; -- for resource_priority begin Initialize (sys); Add_core_unit (sys.Core_units, a_core, To_Unbounded_String ("core1"), preemptive, 0, 1.0, 101, 102, 103, To_Unbounded_String (""), Posix_1003_Highest_Priority_First_Protocol); Add (a_core_unit_table, a_core); Add_Processor (sys.Processors, To_Unbounded_String ("processor1"), a_core_unit_table); Add_Address_Space (sys.Address_Spaces, To_Unbounded_String ("addr1"), To_Unbounded_String ("processor1"), 0, 0, 0, 0); Add_Task (sys.Tasks, To_Unbounded_String ("T1"), To_Unbounded_String ("processor1"), To_Unbounded_String ("addr1"), Periodic_Type, 0, 2, 4, 4, 0, 10, 1, 0, Sched_Fifo); Add_Task (sys.Tasks, To_Unbounded_String ("T2"), To_Unbounded_String ("processor1"), To_Unbounded_String ("addr1"), Periodic_Type, 0, 3, 5, 5, 0, 10, 2, 0, Sched_Fifo); Add_Task (sys.Tasks, To_Unbounded_String ("T3"), To_Unbounded_String ("processor1"), To_Unbounded_String ("addr1"), Periodic_Type, 0, 7, 20, 20, 0, 10, 3, 0, Sched_Fifo); r.task_begin := 1; r.task_end := 1; add (rt, To_Unbounded_String ("T1"), r); add (rt, To_Unbounded_String ("T2"), r); Add_Resource (sys.Resources, To_Unbounded_String ("R1"), 1, 0, 0, To_Unbounded_String ("processor1"), To_Unbounded_String ("addr1"), No_Protocol, rt, 1, Automatic_Assignment); range_end := Search_Resource (sys.Resources, suppress_space (To_Unbounded_String ("R1"))).critical_sections. nb_entries; item := 0; loop Add_One_Task_Dependency_resource (sys.Dependencies, Search_Task (sys.Tasks, Search_Resource (sys.Resources, suppress_space (To_Unbounded_String ("R1"))). critical_sections.entries (item).item), Search_Resource (sys.Resources, suppress_space (To_Unbounded_String ("R1")))); item := item + 1; exit when item >= range_end; end loop; end uncompliant_ravenscar; procedure uncompliant_buffer (sys : out System) is a_core : Core_Unit_Ptr; a_core_unit_table : Core_Units_Table; bt : Buffer_Roles_Table; b : Buffer_Role; T1_ref, T2_ref, T3_ref : Generic_Task_Ptr; begin Initialize (sys); Add_core_unit (sys.Core_units, a_core, To_Unbounded_String ("core1"), preemptive, 0, 1.0, 101, 102, 103, To_Unbounded_String (""), Posix_1003_Highest_Priority_First_Protocol); Add (a_core_unit_table, a_core); Add_Processor (sys.Processors, To_Unbounded_String ("processor1"), a_core_unit_table); Add_Address_Space (sys.Address_Spaces, To_Unbounded_String ("addr1"), To_Unbounded_String ("processor1"), 0, 0, 0, 0); Add_Task (sys.Tasks, T1_ref, To_Unbounded_String ("T1"), To_Unbounded_String ("processor1"), To_Unbounded_String ("addr1"), Periodic_Type, 0, 1, 2, 2, 0, 0, 1, 0, Sched_Fifo); Add_Task (sys.Tasks, T2_ref, To_Unbounded_String ("T2"), To_Unbounded_String ("processor1"), To_Unbounded_String ("addr1"), Periodic_Type, 0, 1, 3, 3, 0, 0, 2, 0, Sched_Fifo); Add_Task (sys.Tasks, T3_ref, To_Unbounded_String ("T3"), To_Unbounded_String ("processor1"), To_Unbounded_String ("addr1"), Periodic_Type, 0, 2, 9, 9, 0, 0, 1, 0, Sched_Fifo); b.the_role := Queuing_Producer; b.size := 1; b.time := 1; add (bt, To_Unbounded_String ("T1"), b); b.the_role := Queuing_Consumer; b.size := 2; b.time := 2; add (bt, To_Unbounded_String ("T2"), b); Add_Buffer (sys.Buffers, To_Unbounded_String ("B1"), 1, To_Unbounded_String ("processor1"), To_Unbounded_String ("addr1"), Qs_Mm1, bt); Add_One_Task_Dependency_time_triggered (sys.Dependencies, Search_Task (sys.Tasks, To_Unbounded_String ("T1")), Search_Task (sys.Tasks, To_Unbounded_String ("T2")), Sampled_Timing); Add_One_Task_Dependency_time_triggered (sys.Dependencies, Search_Task (sys.Tasks, To_Unbounded_String ("T2")), Search_Task (sys.Tasks, To_Unbounded_String ("T3")), Sampled_Timing); Put_Line (To_String (XML_String (sys, 0))); end uncompliant_buffer; procedure Add_Multiple_Periodic_Tasks_To_Set_UUniFast (my_tasks : in out Tasks_Set; N : in Integer; U : in Float) is use Ada.Float_Text_IO; i : Integer; capacity : Integer := 0; period : Integer := 0; deadline : Integer := 0; start_time : Integer := 0; a_offset : Offset_Type; offset_t_a: Offsets_Table; u_array : Random_Tools.Float_Array(0..N-1); flag : Boolean := true; begin i := 0; 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.03) then flag := true; end if; end loop; end loop; while (i < N) loop Initialize(a_offset); Initialize(offset_t_a); capacity :=0; period :=0; deadline :=0; while(capacity <=0 OR period <=0 OR a_offset.offset_value <= 0) loop capacity := Random_Integer(n1 => 10, n2 => 15); period := Integer(Float'Ceiling(Float(capacity)/u_array(i))); start_time := Random_Integer(n1 => 1, n2 => 30); deadline := period; 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 => start_time, Capacity => capacity, Period => period, Deadline => deadline, Jitter => 0, Blocking_Time => 0, Priority => 1, Criticality => 0, Policy => SCHED_FIFO); i := i+1; end loop; end Add_Multiple_Periodic_Tasks_To_Set_UUniFast; procedure Add_Multiple_Periodic_Tasks_Harmonic_With_Direct_Mapped_Instruction_Cache_Utilization_To_Set_UUniFast (my_tasks : in out Tasks_Set; N : in Integer; PU : in Float; CU : in Float; CS : in Integer; RF : in Float; my_instruction_cache : in Instruction_Cache_Ptr; my_cache_access_profiles : out Cache_Access_Profiles_Set) is use Ada.Float_Text_IO; i : Integer; capacity : Integer :=0; period : Integer :=0; deadline : Integer :=0; start_time : Integer := 0; pu_array : Random_Tools.Float_Array(0..N-1); flag : Boolean := true; a_task : Generic_Task_Ptr; a_cache_access_profile : Cache_Access_Profile_Ptr; ------------------------------------------ cu_array : Random_Tools.Float_Array(0..N-1); start_set : Integer :=0; end_set : Integer :=0; ECB : Integer := 0; UCB : Integer := 0; ucb_counter : Integer := 0; Periods : array (0..6) of Integer := (1250,2500,3125,6250,12500,15625,31250); --Periods : array (0..6) of Integer := (10,15,20,30,40,60,120); begin Set_Initialize; i := 0; --GENERATE PROCESSOR UTILIZATION pu_array:=Gen_UUniFast(n => N, U => PU); --GENERATE CACHE UTILIZATION cu_array:=Gen_UUniFast(n => N, U => CU); while (i < N) loop capacity := 0; period := 0; deadline := 0; start_time := Random_Integer(n1 => 1, n2 => 50) * 10; --start_time:= Random_Integer(n1 => 1, n2 => 20); period := Periods(Random_Integer(n1 => 0,n2 => 6)); deadline := period; capacity := Integer(Float'Floor(Float(period) * pu_array(i))); if(capacity <= 0) then capacity :=1; end if; a_cache_access_profile := new Cache_Access_Profile; a_cache_access_profile.name := Suppress_Space(To_Unbounded_String("CAP_" & i'Img)); ---------------------------------------------------------------- ECB := Integer(Float'Floor(Float(CS) * cu_array(i))); UCB := Integer(Float'Floor(Float(ECB) * RF)); end_set := (start_set + ECB) mod CS; ucb_counter := 0; if (start_set < end_set AND ECB < CS) then for j in start_set..end_set-1 loop Add(a_cache_access_profile.ECBs, my_instruction_cache.cache_blocks.Entries(Caches.Cache_Blocks_Range(j))); if(ucb_counter <= UCB) then Add(a_cache_access_profile.UCBs, my_instruction_cache.cache_blocks.Entries(Caches.Cache_Blocks_Range(j))); ucb_counter := ucb_counter + 1; end if; end loop; end if; if (start_set > end_set AND ECB < CS) then for j in start_set..CS-1 loop Add(a_cache_access_profile.ECBs, my_instruction_cache.cache_blocks.Entries(Caches.Cache_Blocks_Range(j))); if(ucb_counter <= UCB) then Add(a_cache_access_profile.UCBs, my_instruction_cache.cache_blocks.Entries(Caches.Cache_Blocks_Range(j))); ucb_counter := ucb_counter + 1; end if; end loop; for j in 0..end_set-1 loop Add(a_cache_access_profile.ECBs, my_instruction_cache.cache_blocks.Entries(Caches.Cache_Blocks_Range(j))); if(ucb_counter <= UCB) then Add(a_cache_access_profile.UCBs, my_instruction_cache.cache_blocks.Entries(Caches.Cache_Blocks_Range(j))); ucb_counter := ucb_counter + 1; end if; end loop; end if; if (ECB > CS) then for j in 0..CS-1 loop Add(a_cache_access_profile.ECBs, my_instruction_cache.cache_blocks.Entries(Caches.Cache_Blocks_Range(j))); if(ucb_counter <= UCB) then Add(a_cache_access_profile.UCBs, my_instruction_cache.cache_blocks.Entries(Caches.Cache_Blocks_Range(j))); ucb_counter := ucb_counter + 1; end if; end loop; end if; start_set := end_set; Add(my_cache_access_profiles,a_cache_access_profile); ---------------------------------------------------------------- Add_Task(My_Tasks => my_tasks, A_Task => a_task, Name => Suppress_Space (To_Unbounded_String ("Task" & i'Img)), Cpu_Name => To_Unbounded_String("CPU_01"), Address_Space_Name => To_Unbounded_String("Address_Space_01"), Task_Type => Periodic_Type, Start_Time => start_time, Capacity => capacity, Period => period, Deadline => deadline, Jitter => 0, Blocking_Time => 0, Priority => 1, Criticality => 0, Policy => SCHED_FIFO, Cache_Access_Profile_Name => a_cache_access_profile.name); i := i+1; end loop; end Add_Multiple_Periodic_Tasks_Harmonic_With_Direct_Mapped_Instruction_Cache_Utilization_To_Set_UUniFast; begin Rand_Int.Reset (G_Int); Rand_Res.Reset (G_Res); end architecture_factory;