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 Processors.extended; use Processors.extended; with Address_Spaces; use Address_Spaces; with Address_Space_Set; use Address_Space_Set; with caches; use caches; use caches.Caches_Table_Package; use processors.core_units_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; use Unbounded_Strings.Unbounded_String_List_Package; with Unchecked_Deallocation; with sets; with Framework_Config; use Framework_Config; with Indexed_Tables; with Double_Util; use Double_Util; with Primitive_XML_Strings; use Primitive_XML_Strings; with indexed_tables; with Offsets; use Offsets; 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; procedure Create_System_From_Scratch (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 begin Initialize (S); initialize_cpt; Add_Mono_Core_Processor_To_System (S, To_Unbounded_String ("cpu1"), Random_Preemptivity, Restrained_Random_Scheduler); Add_Mono_Core_Processor_To_System (S, To_Unbounded_String ("cpu2"), Random_Preemptivity, Restrained_Random_Scheduler); Add_Mono_Core_Processor_To_System (S, To_Unbounded_String ("cpu3"), Random_Preemptivity, Restrained_Random_Scheduler); Add_Address_Space_To_System (S, To_Unbounded_String ("addr1"), To_Unbounded_String ("cpu1")); Add_Address_Space_To_System (S, To_Unbounded_String ("addr2"), get_random_element (S.Processors).name); Add_Multiple_Address_Spaces_To_System (S, 5); --add_multiple_messages_To_System(S,10); Add_Buffer_To_System (S, To_Unbounded_String ("buff1"), To_Unbounded_String ("cpu1"), To_Unbounded_String ("addr1")); Add_Buffer_To_System (S, To_Unbounded_String ("buff2"), To_Unbounded_String ("cpu3"), To_Unbounded_String ("addr1")); Add_Buffer_To_System (S); Add_Multiple_Tasks_To_System (S, 5, Random_Task_Type); Put_Line ("CPU number : " & Get_Number_Of_Elements (S.Processors)'Img); Put_Line ("ADR number : " & Get_Number_Of_Elements (S.Address_Spaces)'Img); Put_Line ("MES number : " & Get_Number_Of_Elements (S.Messages)'Img); Put_Line ("BUF number : " & Get_Number_Of_Elements (S.Buffers)'Img); Put (S.Processors); end Create_System_From_Scratch; -- ------------------------------------------------------------------------------------------- -- 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; procedure Create_Tree_Transaction_System (S : in out System; number_groups : in Integer; number_tasks_per_group : 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; cpu_utilization : in Double := 0.5; min_period : in Integer := 10; max_period : in Integer := 1000; nim_delta : in Integer := 0; priority_variation_prob : in Double := 0.0; processor_variation_prob : in Double := 0.0; non_immediateness_prob : in Double := 0.0) is Preempt : Preemptives_Type; 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, Transaction_Type); -- ***** Tasks generation ***** Add_Multiple_Tasks_To_Tree_Transactions(S, number_tasks_per_group, sched, cpu_utilization, min_period, max_period, nim_delta, priority_variation_prob, processor_variation_prob, non_immediateness_prob); end Create_Tree_Transaction_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 begin Add_Task (S.Tasks, Name, Cpu_Name, Address_Space_Name, Task_Type, 0, 1, cpt, cpt, 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; procedure Add_Multiple_Tasks_To_Tree_Transactions (S : in out System; number_tasks_per_group : in Integer; sched : in Schedulers_Type; cpu_utilization : in Double; min_period : in Integer; max_period : in Integer; nim_delta : in Integer := 0; priority_variation_prob : in Double := 0.0; processor_variation_prob : in Double := 0.0; non_immediateness_prob : in Double := 0.0) is Generic_Add_Multiple_Tasks_To_Tree_Transactions_Exception : exception; package Cpu_Task_Parameters_Package is new Indexed_Tables(Double, Generic_Processor_Ptr, Framework_Config.Max_Processors, 0, Double_Util.Put, Double_Util.Initialize, Put_Name, Get_Name, XML_String, XML_Ref_String); use Cpu_Task_Parameters_Package; subtype Parameter_Per_Cpu is Cpu_Task_Parameters_Package.indexed_table; use Generic_Task_Group_Set; use Generic_Task_List_Package; An_Address_Space : Address_Space_Ptr; Address_Space_Name : Unbounded_String; Cpu_Name : Unbounded_String; Gamma_iterator : Task_Groups_Iterator; Gamma_i : Generic_Task_Group_Ptr; tau_ij_iterator : Generic_Task_Iterator; tau_ij : Generic_Task_Ptr; pred_ij : Generic_Task_Ptr; i : Integer; Tasks_Per_Cpu : Parameter_Per_Cpu; Tmin_Per_Cpu : Parameter_Per_Cpu; Capacity_Per_Cpu : Parameter_Per_Cpu; T_i_min : Integer; T_i_max : Integer; T_i : Integer; max_Ti : Integer; Tmin : Double; max_Tmin : Double; proc : Unbounded_String; n_tasks_i : Integer; denominator : Double; prio_ij : Integer; Computed_Offsets : Boolean := false; -- For testing only ratio : Double; procedure Init_Table (Table : out Parameter_Per_Cpu) is Cpu_iterator : Processors_Iterator; Cpu : Generic_Processor_Ptr; begin Initialize(Table); if not is_empty(S.Processors) then reset_iterator(S.Processors, Cpu_iterator); loop current_element(S.Processors, Cpu, Cpu_iterator); Table.entries(Table.nb_entries).data := 0.0; Table.entries(Table.nb_entries).item := Cpu; Table.nb_entries := Table.nb_entries + 1; exit when is_last_element(S.Processors, Cpu_iterator); next_element(S.Processors, Cpu_iterator); end loop; end if; end Init_Table; procedure Increase_Task_Per_Cpu (Tasks_Per_Cpu : in out Parameter_Per_Cpu; Cpu_Name : in Unbounded_String) is begin if Tasks_Per_Cpu.nb_entries > 0 then for i in 0 .. Tasks_Per_Cpu.nb_entries - 1 loop if Tasks_Per_Cpu.entries(i).item.name = Cpu_Name then Tasks_Per_Cpu.entries(i).data := Tasks_Per_Cpu.entries(i).data + 1.0; return; end if; end loop; end if; end Increase_Task_Per_Cpu; -- Minimum period for tasks on each CPU if we want to achieve Cpu_Utilization with tasks capacities >= 1 procedure Compute_Tmin_Per_Cpu (Tmin_Per_Cpu : in out Parameter_Per_Cpu; Tasks_Per_Cpu : in Parameter_Per_Cpu; cpu_utilization : in Double) is n_tasks_on_cpu : Double; begin if Tasks_Per_Cpu.nb_entries > 0 then for i in 0 .. Tasks_Per_Cpu.nb_entries - 1 loop -- i index same for both tables normally n_tasks_on_cpu := Tasks_Per_Cpu.entries(i).data; Tmin_Per_Cpu.entries(i).data := n_tasks_on_cpu / cpu_utilization; end loop; end if; end Compute_Tmin_Per_Cpu; function Get_Tmin_Per_Cpu (Tmin_Per_Cpu : in Parameter_Per_Cpu; cpu_name : in Unbounded_String) return Double is begin if Tmin_Per_Cpu.nb_entries > 0 then for i in 0 .. Tmin_Per_Cpu.nb_entries - 1 loop if Tmin_Per_Cpu.entries(i).item.name = cpu_name then return Tmin_Per_Cpu.entries(i).data; end if; end loop; end if; raise Generic_Add_Multiple_Tasks_To_Tree_Transactions_Exception; end Get_Tmin_Per_Cpu; -- TODO: This kind of functions needs refactoring function Get_Capacity_Per_Cpu (Capacity_Per_Cpu : in Parameter_Per_Cpu; cpu_name : in Unbounded_String) return Double is begin if Capacity_Per_Cpu.nb_entries > 0 then for i in 0 .. Capacity_Per_Cpu.nb_entries - 1 loop if Capacity_Per_Cpu.entries(i).item.name = cpu_name then return Capacity_Per_Cpu.entries(i).data; end if; end loop; end if; raise Generic_Add_Multiple_Tasks_To_Tree_Transactions_Exception; end Get_Capacity_Per_Cpu; function Get_Offset (tau : Generic_Task_Ptr) return Integer is New_Offset : Offset_Type_Ptr; use Offsets.Offsets_Table_Package; begin if tau.offsets.nb_entries > 0 then for I in 0 .. tau.offsets.nb_entries - 1 loop if tau.offsets.entries(I).activation = 0 then return tau.offsets.entries(I).offset_value; end if; end loop; end if; New_Offset := new Offset_Type; New_Offset.offset_value := 0; New_Offset.activation := 0; Add(tau.offsets, New_Offset.all); return 0; end Get_Offset; procedure Compute_Successors_Offset (tau_ij : Generic_Task_Ptr) is use Offsets.Offsets_Table_Package; use Task_Dependencies.Half_Dep_Set; New_Offset : Offset_Type_Ptr; A_Task_Dependencies_Iterator : Tasks_Dependencies_Iterator; A_Half_Dep : Dependency_Ptr; begin if not is_empty(S.Dependencies.Depends) then reset_iterator(S.Dependencies.Depends, A_Task_Dependencies_Iterator); loop current_element(S.Dependencies.Depends, A_Half_Dep, A_Task_Dependencies_Iterator); if A_Half_Dep.type_of_dependency = Precedence_Dependency then if A_Half_Dep.precedence_source.name = tau_ij.name then New_Offset := new Offset_Type; New_Offset.activation := 0; New_Offset.offset_value := Get_Offset(tau_ij) + tau_ij.capacity; if Random_Integer(100) < Integer(non_immediateness_prob * 100.0) then New_Offset.offset_value := New_Offset.offset_value + Random_Integer(nim_delta) + 1; end if; Add(A_Half_Dep.precedence_sink.offsets, New_Offset.all); Compute_Successors_Offset(A_Half_Dep.precedence_sink); end if; end if; exit when is_last_element(S.Dependencies.Depends, A_Task_Dependencies_Iterator); next_element(S.Dependencies.Depends, A_Task_Dependencies_Iterator); end loop; end if; end Compute_Successors_Offset; begin -- TODO raise exception if parameters are not correct (e.g. number_of_tasks_per_group <= 0) -- GENERAL IDEA : Compute T_i and C_ij according to cpu_utilization, then re-compute all offsets and priorities since they depend on C_ij an T_i -- n tasks on CPU with cpu_utilization -- If workload is distributed among tasks on CPU (i.e. tasks have the same capacity) and a task's capacity cannot be lower than 1 then -- T_min = n / cpu_utilization -- Any transaction that has tasks on CPU must thus have T >= T_min -- Once this is assured, to compute C for all tasks on CPU: -- tau_x on CPU -- C_x = cpu_utilization / Sum_{i=1}^{n_Gamma} (nb(tau_x) in Gamma_i / T_i) Init_Table(Tasks_Per_Cpu); Init_Table(Tmin_Per_Cpu); Init_Table(Capacity_Per_Cpu); i := 0; reset_iterator(S.Task_Groups, Gamma_iterator); loop current_element(S.Task_Groups, Gamma_i, Gamma_iterator); for j in 0 .. number_tasks_per_group - 1 loop -- 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; if j > 0 then pred_ij := get_random_element(Gamma_i.task_list); if Random_Integer(100) >= Integer(processor_variation_prob * 100.0) then -- Higher than threshold so we use the pred's cpu Address_Space_Name := pred_ij.address_space_name; Cpu_Name := pred_ij.cpu_name; end if; end if; Add_Task (S.Tasks, S.Task_Groups, Gamma_i.name, Suppress_Space("tau_" & i'Img & j'Img), Cpu_Name, Address_Space_Name, Periodic_Type, 0, -- start_time 1, -- capacity 1, -- period 9999999, -- deadline 0, -- jitter 0, -- blocking 1, -- priority 0, -- criticality SCHED_FIFO); if j > 0 then Add_One_Task_Dependency (S.Dependencies, pred_ij, Search_Task(S.Tasks, Suppress_Space("tau_" & i'Img & j'Img))); end if; Increase_Task_Per_Cpu(Tasks_Per_Cpu, Cpu_Name); end loop; i := i + 1; exit when is_last_element(S.Task_Groups, Gamma_iterator); next_element(S.Task_Groups, Gamma_iterator); end loop; Compute_Tmin_Per_Cpu(Tmin_Per_Cpu, Tasks_Per_Cpu, Cpu_Utilization); -- T_i handling max_Ti := 0; reset_iterator(S.Task_Groups, Gamma_iterator); loop current_element(S.Task_Groups, Gamma_i, Gamma_iterator); -- Loop through tasks in Gamma_i, check each task's CPU and choose the max of T_min per CPU max_Tmin := 0.0; reset_head_iterator(Gamma_i.task_list, tau_ij_iterator); loop current_element(Gamma_i.task_list, tau_ij, tau_ij_iterator); Tmin := Get_Tmin_Per_Cpu(Tmin_Per_Cpu, tau_ij.cpu_name); if Tmin > max_Tmin then max_Tmin := Tmin; end if; exit when is_tail_element(Gamma_i.task_list, tau_ij_iterator); next_element(Gamma_i.task_list, tau_ij_iterator); end loop; -- Verify user parameters (min and max period cannot be lower than Ceiling(max_Tmin) T_i_min := min_period; T_i_max := max_period; if T_i_min < Integer(Double'Ceiling(max_Tmin)) then T_i_min := Integer(Double'Ceiling(max_Tmin)); end if; if T_i_max < Integer(Double'Ceiling(max_Tmin)) then T_i_max := Integer(Double'Ceiling(max_Tmin)); end if; -- Loop again to set T_i = rand(...) for each tau_ij in Gamma_i T_i := Random_Integer(T_i_min, T_i_max); Gamma_i.period := T_i; reset_head_iterator(Gamma_i.task_list, tau_ij_iterator); loop current_element(Gamma_i.task_list, tau_ij, tau_ij_iterator); Periodic_Task_Ptr(tau_ij).period := T_i; exit when is_tail_element(Gamma_i.task_list, tau_ij_iterator); next_element(Gamma_i.task_list, tau_ij_iterator); end loop; if T_i > max_Ti then max_Ti := T_i; end if; exit when is_last_element(S.Task_Groups, Gamma_iterator); next_element(S.Task_Groups, Gamma_iterator); end loop; -- Comupte C for each CPU for i in 0 .. Capacity_Per_Cpu.nb_entries - 1 loop proc := Capacity_Per_Cpu.entries(i).item.name; denominator := 0.0; reset_iterator(S.Task_Groups, Gamma_iterator); loop current_element(S.Task_Groups, Gamma_i, Gamma_iterator); -- Get number of tasks on cpu "proc" n_tasks_i := 0; reset_head_iterator(Gamma_i.task_list, tau_ij_iterator); loop current_element(Gamma_i.task_list, tau_ij, tau_ij_iterator); if tau_ij.cpu_name = proc then n_tasks_i := n_tasks_i + 1; end if; exit when is_tail_element(Gamma_i.task_list, tau_ij_iterator); next_element(Gamma_i.task_list, tau_ij_iterator); end loop; -- Update denominator to be part of the cpu_utiilzation / denominator division T_i := Gamma_i.period; denominator := denominator + Double(n_tasks_i) / Double(T_i); exit when is_last_element(S.Task_Groups, Gamma_iterator); next_element(S.Task_Groups, Gamma_iterator); end loop; if denominator > 0.0 then Capacity_Per_Cpu.entries(i).data := Double(cpu_utilization) / denominator; end if; end loop; -- Compute each task's priority (inversely proportional to T_ij with prio = 1 for max(T_ij) so k = max(T_ij)) and update capacity reset_iterator(S.Task_Groups, Gamma_iterator); loop current_element(S.Task_Groups, Gamma_i, Gamma_iterator); reset_head_iterator(Gamma_i.task_list, tau_ij_iterator); loop current_element(Gamma_i.task_list, tau_ij, tau_ij_iterator); -- Comupte priority and variate if prob test passes prio_ij := max_Ti / Periodic_Task_Ptr(tau_ij).period; if Random_Integer(100) < Integer(priority_variation_prob * 100.0) then prio_ij := Random_Integer(255) + 1; end if; if prio_ij > 255 then prio_ij := 255; elsif prio_ij < 1 then prio_ij := 1; end if; tau_ij.priority := Priority_Range(prio_ij); -- Update capacity computed previously for tau_ij's CPU (floor it before) tau_ij.capacity := Integer(Double'Floor(Get_Capacity_Per_Cpu(Capacity_Per_Cpu, tau_ij.cpu_name))); exit when is_tail_element(Gamma_i.task_list, tau_ij_iterator); next_element(Gamma_i.task_list, tau_ij_iterator); end loop; exit when is_last_element(S.Task_Groups, Gamma_iterator); next_element(S.Task_Groups, Gamma_iterator); end loop; -- Compute offsets and modify immediateness reset_iterator(S.Task_Groups, Gamma_iterator); loop current_element(S.Task_Groups, Gamma_i, Gamma_iterator); Computed_Offsets := false; reset_head_iterator(Gamma_i.task_list, tau_ij_iterator); loop current_element(Gamma_i.task_list, tau_ij, tau_ij_iterator); if not Has_Predecessor(S.Dependencies, tau_ij) then Compute_Successors_Offset(tau_ij); Computed_Offsets := true; end if; exit when is_tail_element(Gamma_i.task_list, tau_ij_iterator) or Computed_Offsets; next_element(Gamma_i.task_list, tau_ij_iterator); end loop; exit when is_last_element(S.Task_Groups, Gamma_iterator); next_element(S.Task_Groups, Gamma_iterator); end loop; -- Test offsets -- reset_iterator(S.Task_Groups, Gamma_iterator); -- loop -- current_element(S.Task_Groups, Gamma_i, Gamma_iterator); -- -- put_line("----- " & to_string(gamma_i.name) & "(Ti = " & Gamma_i.period'Img & ")"); -- -- reset_head_iterator(Gamma_i.task_list, tau_ij_iterator); -- loop -- current_element(Gamma_i.task_list, tau_ij, tau_ij_iterator); -- -- if get_offset(tau_ij) > 0 then -- put_line(to_string(tau_ij.name) & " (pred = " & to_string(Get_A_Predecessor(S.Dependencies, tau_ij).name) & ") : " & get_offset(tau_ij)'Img & " + "& tau_ij.capacity'Img); -- else -- put_line(to_string(tau_ij.name) & " : " & get_offset(tau_ij)'Img & " + "& tau_ij.capacity'Img); -- end if; -- exit when is_tail_element(Gamma_i.task_list, tau_ij_iterator); -- next_element(Gamma_i.task_list, tau_ij_iterator); -- end loop; -- -- exit when is_last_element(S.Task_Groups, Gamma_iterator); -- next_element(S.Task_Groups, Gamma_iterator); -- end loop; -- Test CPU utilization -- put_line("***** CPU Utilizations *****"); -- for i in 0 .. Capacity_Per_Cpu.nb_entries - 1 loop -- proc := Capacity_Per_Cpu.entries(i).item.name; -- ratio := 0.0; -- -- reset_iterator(S.Task_Groups, Gamma_iterator); -- loop -- current_element(S.Task_Groups, Gamma_i, Gamma_iterator); -- -- reset_head_iterator(Gamma_i.task_list, tau_ij_iterator); -- loop -- current_element(Gamma_i.task_list, tau_ij, tau_ij_iterator); -- -- if tau_ij.cpu_name = proc then -- ratio := ratio + Double(tau_ij.capacity) / Double(Periodic_Task_Ptr(tau_ij).period); -- end if; -- -- exit when is_tail_element(Gamma_i.task_list, tau_ij_iterator); -- next_element(Gamma_i.task_list, tau_ij_iterator); -- end loop; -- -- exit when is_last_element(S.Task_Groups, Gamma_iterator); -- next_element(S.Task_Groups, Gamma_iterator); -- end loop; -- -- put_line(to_string(proc) & " @ " & ratio'Img); -- end loop; end Add_Multiple_Tasks_To_Tree_Transactions; -- 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; A_Task : Generic_Task_Ptr; begin i := 1; protocol := Restrained_Random_Resource_Type; A_Task := get_random_element(S.Tasks); name1 := A_Task.name; loop name2 := get_random_element (S.Tasks).name; exit when name1 /= name2 or get_number_of_elements(S.Tasks) = 1; end loop; -- REMOD HERE --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.capacity] 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); 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 (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; 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; 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); 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 (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; -- 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 (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 (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)); A_core_unit := new extended_core_unit; A_core_unit.name := name_core_unit; set_core_unit_scheduler (extended_Core_Unit_Ptr (A_core_unit), Preempt, 0, 1.0, 0, 0, 0, Empty_String, Sched); add(S.Core_units, A_core_unit); -- 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)); A_core_unit := new extended_core_unit; A_core_unit.name := name_core_unit; set_core_unit_scheduler (extended_Core_Unit_Ptr (A_core_unit), Preemptivity, 0, 0.0, 0, 0, 0, Empty_String, Sched); add(S.Core_units, A_core_unit); -- 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)), empty_string, 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)), empty_string, 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, Empty_String, 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)); A_Core_Unit := new Extended_Core_Unit; A_Core_Unit.name := name_core_unit; set_core_unit_scheduler (extended_Core_Unit_Ptr (A_Core_Unit), Preemptivity, 0, 1.0, 0, 0, 0, Empty_String, Sched); add(S.Core_units, A_Core_Unit); 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), Empty_String, 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 Queuing_Buffer_Dependency; when depend_range (2) => return 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"), to_unbounded_string("a_network"), 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 (sys.Dependencies, Search_Task(sys.Tasks,to_unbounded_string("T1")), Search_Task(sys.Tasks,to_unbounded_string("T2")), Sampled_Timing); Add_One_Task_Dependency (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"), to_unbounded_string("a_network"), 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 (sys.Dependencies, Search_Task(sys.Tasks,to_unbounded_string("T1")), Search_Task(sys.Tasks,to_unbounded_string("T2")), Sampled_Timing); Add_One_Task_Dependency (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"), to_unbounded_string("a_network"), 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"), to_unbounded_string("a_network"), 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; 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"), to_unbounded_string("a_network"), 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); range_end := Search_Resource (sys.Resources, Suppress_Space (To_Unbounded_String ("R1"))). critical_sections.Nb_Entries; item := 0; loop Add_One_Task_Dependency (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; 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"), to_unbounded_string("a_network"), 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); range_end := Search_Resource (sys.Resources, Suppress_Space (To_Unbounded_String ("R1"))). critical_sections.Nb_Entries; item := 0; loop Add_one_Task_Dependency (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"), to_unbounded_string("a_network"), 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 (sys.Dependencies, Search_Task(sys.Tasks,to_unbounded_string("T1")), Search_Task(sys.Tasks,to_unbounded_string("T2")), Sampled_Timing); Add_One_Task_Dependency (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; begin Rand_Int.Reset(G_Int); Rand_Res.Reset(G_Res); end architecture_factory;