------------------------------------------------------------------------------ ------------------------------------------------------------------------------ -- 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.Exceptions; use Ada.Exceptions; with Scheduler.user_defined; use Scheduler.user_defined; with Scheduler.user_defined.interpreted.pipeline; use Scheduler.user_defined.interpreted.pipeline; with Scheduler.user_defined.interpreted.Automata; use Scheduler.user_defined.interpreted.Automata; with Scheduler.user_defined.Generated.compiled; use Scheduler.user_defined.Generated.compiled; with Scheduler.Fixed_Priority.Dm; use Scheduler.Fixed_Priority.Dm; with Scheduler.Fixed_Priority.Rm; use Scheduler.Fixed_Priority.Rm; with Scheduler.Fixed_Priority.Hpf; use Scheduler.Fixed_Priority.Hpf; with Scheduler.Dynamic_Priority.Edf; use Scheduler.Dynamic_Priority.Edf; with Scheduler.Dynamic_Priority.Llf; use Scheduler.Dynamic_Priority.Llf; with Scheduler.Dynamic_Priority.Muf.Deadline_Based; use Scheduler.Dynamic_Priority.Muf.Deadline_Based; with Scheduler.Dynamic_Priority.Muf.Laxity_Based; use Scheduler.Dynamic_Priority.Muf.Laxity_Based; with Scheduler.Dynamic_Priority.D_Over; use Scheduler.Dynamic_Priority.D_Over; with Scheduler.Time_Sharing_Based_On_Wait_Time; use Scheduler.Time_Sharing_Based_On_Wait_Time; with Scheduler.Time_Sharing_Based_On_Cpu_Usage; use Scheduler.Time_Sharing_Based_On_Cpu_Usage; with Scheduler.Round_Robin; use Scheduler.Round_Robin; with Scheduler.Hierarchical; use Scheduler.Hierarchical; with Scheduler.Hierarchical.Round_Robin; use Scheduler.Hierarchical.Round_Robin; with Scheduler.Hierarchical.cyclic; use Scheduler.Hierarchical.cyclic; with Scheduler.Hierarchical.offline; use Scheduler.Hierarchical.offline; with Scheduler.Fixed_Priority.aperiodic_server; use Scheduler.Fixed_Priority.aperiodic_server; with Scheduler.Fixed_Priority.aperiodic_server.polling; use Scheduler.Fixed_Priority.aperiodic_server.polling; with Scheduler.fixed_priority.aperiodic_server.priority_exchange; use Scheduler.fixed_priority.aperiodic_server.priority_exchange; with Scheduler.Fixed_Priority.aperiodic_server.deferrable; use Scheduler.Fixed_Priority.aperiodic_server.deferrable; with Scheduler.fixed_priority.aperiodic_server.sporadic; use Scheduler.fixed_priority.aperiodic_server.sporadic; with Scheduler.multiprocessor_specific; use Scheduler.multiprocessor_specific; with Scheduler.multiprocessor_specific.pfair; use Scheduler.multiprocessor_specific.pfair; with Scheduler.multiprocessor_specific.pfair.PF; use Scheduler.multiprocessor_specific.pfair.PF; with Scheduler.multiprocessor_specific.edzl; use Scheduler.multiprocessor_specific.edzl; with Scheduler.multiprocessor_specific.run; use Scheduler.multiprocessor_specific.run; with Scheduler.multiprocessor_specific.llref; use Scheduler.multiprocessor_specific.llref; with Scheduler.DAG.Highest_Level_First_Estimated_Times; use Scheduler.DAG.Highest_Level_First_Estimated_Times; with scheduler.nothing; use scheduler.nothing; with Processors; use Processors; with processor_set; use processor_set; with address_spaces; use address_spaces; with core_units; use core_units; use core_units.Core_Units_Table_Package; with task_set; use task_set; with Translate; use Translate; with Objects; use Objects; with Objects.extended; use Objects.extended; with initialize_framework; use initialize_framework; with scheduler_interface.extended; use scheduler_interface.extended; with text_io; use text_io; package body scheduler_builder is -- build a scheduler from its Cheddar ADL specification -- function build_a_scheduler (a_processor : Generic_Processor_Ptr) return generic_scheduler_ptr is a_core_unit : core_unit_ptr; begin if a_processor.processor_type = Monocore_type then a_core_unit:=Mono_Core_Processor_Ptr (a_processor).core; else a_core_unit:=Multi_Cores_Processor_Ptr (a_processor).cores.entries(0); end if; return build_a_scheduler(a_core_unit, a_processor); end build_a_scheduler; function build_a_scheduler (a_core_unit : core_unit_Ptr; a_processor : generic_processor_ptr) return generic_scheduler_ptr is a_scheduler : generic_scheduler_ptr; begin case a_core_unit.scheduling.Scheduler_type is when Rate_Monotonic_Protocol => A_scheduler := new Rm_Scheduler; when Deadline_Monotonic_Protocol => A_scheduler := new Dm_Scheduler; when Posix_1003_Highest_Priority_First_Protocol => A_scheduler := new Hpf_Scheduler; when Earliest_Deadline_First_Protocol => A_scheduler := new Edf_Scheduler; when Least_Laxity_First_Protocol => A_scheduler := new Llf_Scheduler; when Round_Robin_Protocol => A_scheduler := new Round_Robin_Scheduler; when Maximum_Urgency_First_Based_On_Deadline_Protocol => A_scheduler := new Deadline_Muf_Scheduler; when Maximum_Urgency_First_Based_On_Laxity_Protocol => A_scheduler := new Laxity_Muf_Scheduler; when Time_Sharing_Based_On_Wait_Time_Protocol => A_scheduler := new Time_Sharing_Based_On_Wait_Time_Scheduler; when Time_Sharing_Based_On_Cpu_Usage_Protocol => A_scheduler := new Time_Sharing_Based_On_Cpu_Usage_Scheduler; when D_Over_Protocol => A_scheduler := new D_Over_Scheduler; when pipeline_User_Defined_Protocol => A_scheduler := new pipeline_user_defined_Scheduler; when Automata_User_Defined_Protocol => A_scheduler := new Automata_User_Defined_Scheduler; when Compiled_User_Defined_Protocol => A_scheduler := new compiled_user_defined_Scheduler; when Hierarchical_Cyclic_Protocol => A_scheduler := new Hierarchical_cyclic_Scheduler; when Hierarchical_Offline_Protocol => A_scheduler := new Hierarchical_offline_Scheduler; when Hierarchical_Round_Robin_Protocol => A_scheduler := new Hierarchical_Round_Robin_Scheduler; when Hierarchical_Fixed_Priority_Protocol => A_scheduler := new Rm_Scheduler; when DAG_highest_level_first_estimated_times_protocol => A_scheduler := new DAG_highest_level_first_estimated_times_Scheduler; when hierarchical_polling_aperiodic_server_protocol => A_scheduler := new polling_aperiodic_server_Scheduler; when hierarchical_deferrable_aperiodic_server_protocol => A_scheduler := new deferrable_aperiodic_server_Scheduler; when hierarchical_priority_exchange_aperiodic_server_protocol => A_Scheduler := new priority_exchange_aperiodic_server_scheduler; when hierarchical_sporadic_aperiodic_server_protocol => A_Scheduler := new sporadic_aperiodic_server_scheduler; when Proportionate_Fair_PF_Protocol | Proportionate_Fair_PD_Protocol | Proportionate_Fair_PD2_Protocol => A_scheduler := new multiprocessor_pfair_pf_Scheduler; when reduction_to_uniprocessor_protocol => A_scheduler := new multiprocessor_run_Scheduler; when earliest_deadline_zero_laxity_protocol => A_scheduler := new multiprocessor_edzl_Scheduler; when Largest_Local_Remaining_Execution_First_Protocol => A_scheduler := new multiprocessor_llref_Scheduler; when User_Defined_Protocol | No_Scheduling_Protocol => Raise_Exception (processor_set.Invalid_Parameter'Identity, To_String (lb_core_unit (Current_Language) & " " & A_core_unit.name & " : " & Lb_Invalid_Scheduler (Current_Language))); end case; -- Set scheduling parameters -- A_scheduler.parameters:=a_core_unit.scheduling; if (a_core_unit.scheduling.Scheduler_type = Automata_User_Defined_Protocol) then Set_Behavior_File_Name (Automata_User_Defined_Scheduler (A_scheduler.all), a_core_unit.scheduling.user_defined_scheduler_source_file_name); Set_Automaton_Name (Automata_User_Defined_Scheduler (A_scheduler.all), a_core_unit.scheduling.automaton_name); end if; if (a_core_unit.scheduling.Scheduler_type = pipeline_User_Defined_Protocol) then Set_Behavior_File_Name (pipeline_user_defined_Scheduler (A_scheduler.all), a_core_unit.scheduling.user_defined_scheduler_source_file_name); end if; Set_Quantum (A_scheduler.all, a_core_unit.scheduling.Quantum); Set_Preemptive (A_scheduler.all, a_core_unit.scheduling.Preemptive_type); -- Core unit and processor corresponding to this scheduler -- (used to drive task migration for example) -- A_scheduler.corresponding_core_unit := A_core_unit; a_scheduler.corresponding_processor := a_processor; -- Allow the scheduler to know if the previous task is completed -- or not ... and then, could be re-elected later -- (for non preemptive scheduling protocols) -- a_scheduler.previous_running_task_is_not_completed:= False; -- Last scheduled task -- a_scheduler.previously_Elected := Tasks_Range'First; return a_scheduler; end build_a_scheduler; function build_a_scheduler (a_addr : address_space_ptr; a_processor : generic_processor_ptr) return generic_scheduler_ptr is sched : generic_scheduler_ptr; begin case a_addr.Scheduling.scheduler_type is when Rate_Monotonic_Protocol => sched := new Rm_Scheduler; when Deadline_Monotonic_Protocol => sched := new Dm_Scheduler; when Posix_1003_Highest_Priority_First_Protocol => sched := new Hpf_Scheduler; when Earliest_Deadline_First_Protocol => sched := new Edf_Scheduler; when Least_Laxity_First_Protocol => sched := new Llf_Scheduler; when Round_Robin_Protocol => sched := new Round_Robin_Scheduler; when Maximum_Urgency_First_Based_On_Deadline_Protocol => sched := new Deadline_Muf_Scheduler; when Maximum_Urgency_First_Based_On_Laxity_Protocol => sched := new Laxity_Muf_Scheduler; when Time_Sharing_Based_On_Wait_Time_Protocol => sched := new Time_Sharing_Based_On_Wait_Time_Scheduler; when Time_Sharing_Based_On_Cpu_Usage_Protocol => sched := new Time_Sharing_Based_On_Cpu_Usage_Scheduler; when D_Over_Protocol => sched := new D_Over_Scheduler; when Automata_User_Defined_Protocol => sched := new Automata_User_Defined_Scheduler; when Compiled_User_Defined_Protocol => sched := new compiled_user_defined_Scheduler; when DAG_highest_level_first_estimated_times_protocol => sched := new DAG_highest_level_first_estimated_times_Scheduler; when No_Scheduling_Protocol => sched := new No_Scheduler; when others => null; end case; if (a_addr.Scheduling.scheduler_type = Automata_User_Defined_Protocol) then Set_Behavior_File_Name (Automata_User_Defined_Scheduler ( sched.all), a_addr.scheduling.user_defined_scheduler_source_file_name); Set_Automaton_Name (Automata_User_Defined_Scheduler ( sched.all), a_addr.scheduling.automaton_name); end if; Set_Quantum (sched.all, a_addr.scheduling.Quantum); Set_Preemptive (sched.all, a_addr.scheduling.Preemptive_type); -- Core unit and processor corresponding to this scheduler -- (used to drive task migration for example) -- sched.corresponding_address_space := A_addr; sched.corresponding_processor := a_processor; sched.corresponding_core_unit := mono_core_processor_ptr(a_processor).core; return sched; end build_a_scheduler; function build_a_scheduler (a_deployment : generic_deployment_ptr) return generic_scheduler_ptr is begin return null; end build_a_scheduler; end scheduler_builder;