------------------------------------------------------------------------------ ------------------------------------------------------------------------------ -- 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_Groups; use Task_Groups; with Buffers; use Buffers; with Messages; use Messages; with Dependencies; use Dependencies; with Resources; use Resources; with Systems; use Systems; with Processors; use Processors; with Processor_Set; use Processor_Set; with processor_interface; use processor_interface; with Core_Units; use Core_Units; use Core_Units.Core_Units_Table_Package; with Task_Set; use Task_Set; with convert_strings; with convert_unbounded_strings; with Text_IO; use Text_IO; with Ada.Numerics.Aux; use Ada.Numerics.Aux; with Scheduler_Interface; use Scheduler_Interface; with Systems; use Systems; with Ada.Finalization; with unbounded_strings; use unbounded_strings; use unbounded_strings.unbounded_string_list_package; with Unchecked_Deallocation; with Ada.Numerics.Discrete_Random; with Cache_Set; use Cache_Set; with Caches; use Caches; with Cache_Block_Set; use Cache_Block_Set; with Cache_Access_Profile_Set; use Cache_Access_Profile_Set; package architecture_factory is ------------------------------------------------------- -- This package contains procedures to build a system architecture with Cheddar architecture language. -- Procedure are grouped by the type of entity they add to the system. -- There are three types of procedures : -- (1) procedures building a complete system (group n°0) -- (2) procedures adding an entity or a group of entities to a system -- Those groups of procedures are numbered from 1 to 12, -- according to the order in which they need to be added -- (3) functions returning ramdomly picked entity types (with a normal law). ------------------------------------------------------- type Int_Range is range 0 .. 99999; package Rand_Int is new Ada.Numerics.Discrete_Random (Int_Range); G_Int : Rand_Int.Generator; type Resource_range is range 0 .. 2; package Rand_Res is new Ada.Numerics.Discrete_Random (Resource_range); G_Res : Rand_Res.Generator; Building_Architecture_Exception : exception; procedure initialize_cpt; ------------------------------------------------------- -- (1) procedures building a complete system (group n°0) ------------------------------------------------------- -- 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); 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); 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); -- Generate randomly a schedulable system -- from a set of given arguments: -- 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); -- Task set Generation based on : -- Goossens, J., & Macq, C. (2001) And Bertout (2014). -- The method is as follow : -- -- • Ui : each task utilization (Ci/Ti) is computed following -- the classic UUnifast method [BINI and BUTTAZZO'2005] from the overall -- utilization factor of the processor cpu_utilization. -- -- • Ti : each task period is uniformly distributed between -- a set of a maximum of N_Different_Periods different periods by task set -- using method of [Goosens'2001], ensuring that the simulation can -- be limited to a reasonable hyper-period. -- -- • Ci = Ti × Ui : the task capacity is computed as -- the product of its period and its utilization factor -- -- • Di = Round((Ti − Ci ) * Random(D_Min, D_Max)) + Ci -- with 0 ≤ d1 ≤ d2. -- This computation comes from [Goosens'2001] and use -- the following functions: rand(D_Min, D_Max) which -- returns a pseudo-random real number uniformly -- distributed in the interval [D_Min, D_Max] and round(x) which -- returns the closest integer to x. -- We notice that : -- D_Min = D_Max = 1 corresponds to implicit deadlines and -- D_Min ≤ D_Max = 1 to constrained deadlines. -- 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); ------------------------------------------------------------- -- (2) procedures adding an entity or a group of entities to a 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); 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); 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); 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); 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); 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); procedure Add_Multiple_Tasks_To_System (S : in out System; N : Integer; Task_Type : in Tasks_Type); procedure Add_Multiple_Frame_Tasks_To_System (S : in out System; number_frames : in Integer; mf_period : in Integer; sync_ratio : in Double); procedure Add_Multiple_Periodic_Tasks_To_Set_UUniFast (my_tasks : in out Tasks_Set; N : in Integer; U : in Float); 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); procedure Add_Multiple_Periodic_Tasks_No_Offset_With_Direct_Mapped_Instruction_Cache_Utilization_To_Set_UUniFast (my_tasks : in out Tasks_Set; Min_Period : in Integer; Max_Period : in Integer; 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); -- 9 --------= Resources_Set =-------- procedure Add_Resource_To_System (S : in out System; N_dependent_tasks : Integer); procedure Add_Resource_To_System (S : in out System; Name : in Unbounded_String; N_dependent_tasks : Integer); procedure Add_Multiple_Resources_To_System (S : in out System; N : Integer); -- Add_Resource_Set_To_System is a procedure that allows to generate a set of resources -- (and their critical section) shared betweew the tasks -- of the system given in parameter. -- The resource set generator works as follows: -- 1) The number of resources is given in parameter -- -- 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 * #fcts ] -- -- 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 -- 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); -- 3 --------= Messages_Set =-------- procedure Add_Message_To_System (S : in out System); procedure Add_Message_To_System (S : in out System; Name : in Unbounded_String); procedure Add_Multiple_Messages_To_System (S : in out System; N : Integer); -- 10 --------= Dependecies =-------- procedure Add_Time_Triggered_Communication_Dependency_To_System (S : in out System); procedure Add_Dependency_To_System (S : in out System; Name : in Unbounded_String); procedure Add_Multiple_Dependencies_To_System (S : in out System; N : Integer); procedure Add_Multiple_MF_Precedence_Dependencies_To_System (S : in out System; number_precedences : in Integer; number_groups : in Integer; sync_ratio : in Double); -- 11 --------= Task_Groups_Set =-------- procedure Add_Task_Group_To_System (S : in out System; Task_Group_Type : in Task_Groups_type); procedure Add_Task_Group_To_System (S : in out System; Name : in Unbounded_String; Task_Group_Type : in Task_Groups_type); procedure Add_Multiple_Task_Groups_To_System (S : in out System; N : Integer; Task_Group_Type : in Task_Groups_type); -- 12 --------= Deployments =-------- -- 1 --------= Core_Units_Set =-------- procedure Add_Core_Unit_To_System (S : in out System); procedure Add_Core_Unit_To_System (S : in out System; Sched : in Schedulers_Type); procedure Add_Core_Unit_To_System (S : in out System; Name : in Unbounded_String); 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); -- 2 --------= Processors_Set =-------- procedure Add_Mono_Core_Processor_To_System (S : in out System; Preemptivity : in Preemptives_Type; Sched : in Schedulers_Type); procedure Add_Mono_Core_Processor_To_System (S : in out System; Preemptivity : in Preemptives_Type; Sched : in Schedulers_Type; Core : Core_Unit_Ptr); procedure Add_Mono_Core_Processor_To_System (S : in out System; Name : in Unbounded_String; Preemptivity : in Preemptives_Type; Sched : in Schedulers_Type); procedure Add_Multiple_Mono_Core_Processors_To_System (S : in out System; N : Integer); procedure Add_Multi_Cores_Processor_To_System (S : in out System; Number_Core_Units : in Integer; Preemptivity : in Preemptives_Type; Sched : in Schedulers_Type); 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); -- 7 --------= Buffers_Set =-------- procedure Add_Buffer_To_System (S : in out System); procedure Add_Buffer_To_System (S : in out System; Cpu_Name : in Unbounded_String; Address_Space_Name : in Unbounded_String); procedure Add_Buffer_To_System (S : in out System; Name : in Unbounded_String; Cpu_Name : in Unbounded_String; Address_Space_Name : in Unbounded_String); procedure Add_Multiple_Buffers_To_System (S : in out System; N : Integer); -- 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); procedure Add_Address_Space_To_System (S : in out System; Name : in Unbounded_String; cpu_name : Unbounded_String); procedure Add_Multiple_Address_Spaces_To_System (S : in out System; N : Integer); procedure Add_Multiple_Address_Spaces_Consistently_To_System (S : in out System; Number_Processors : in Integer; Number_Address_Spaces : in Integer); -- Added Functions for DP Prototype Demonstration -- procedure compliant_time_triggered_communication (sys : out System); procedure uncompliant_time_triggered_communication (sys : out System); procedure compliant_ravenscar (sys : out System); procedure uncompliant_ravenscar (sys : out System); procedure compliant_unplugged (sys : out System); procedure uncompliant_unplugged (sys : out System); procedure uncompliant_buffer (sys : out System); --------------------------------------------------------- -- (3) functions returning ramdomly picked entity types (with a normal law). --------------------------------------------------------- -- Functions returning ramdomly choosen entity types -- function Random_Preemptivity return Preemptives_Type; function Random_Scheduler return Schedulers_Type; function Restrained_Random_Scheduler return Schedulers_Type; function Random_Dependency_Type return Dependency_Type; function Random_Resource_Type return Resources_Type; function Restrained_Random_Resource_Type return Resources_Type; function Random_Task_Type return Tasks_Type; -- Random_Integer (n : Integer) returns a random integer in the range [0 , n[ function Random_Integer (n : Integer) return Integer; -- Random_Integer (n1 : Integer; n2 : Integer) returns a random integer in the range [n1 , n2] function Random_Integer (n1 : Integer; n2 : Integer) return Integer; end architecture_factory;