------------------------------------------------------------------------------
------------------------------------------------------------------------------
-- 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-2023, Frank Singhoff, Alain Plantec, Jerome Legrand,
-- Hai Nam Tran, Stephane Rubini
--
-- The Cheddar project was started in 2002 by
-- Frank Singhoff, Lab-STICC UMR CNRS 6285, Universite 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 README.md
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; if not, write to the Free Software
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--
--
-- Contact : cheddar@listes.univ-brest.fr
--
------------------------------------------------------------------------------
-- Last update :
-- $Rev$
-- $Date$
-- $Author: singhoff $
------------------------------------------------------------------------------
------------------------------------------------------------------------------
with Ada.Text_IO; use Ada.Text_IO;
with GNAT.Current_Exception; use GNAT.Current_Exception;
with Doubles; use Doubles;
with xml_tag; use xml_tag;
with scheduler.fixed_priority; use scheduler.fixed_priority;
with scheduler.fixed_priority.dm; use scheduler.fixed_priority.dm;
with scheduler.fixed_priority.rm; use scheduler.fixed_priority.rm;
with double_util; use double_util;
with translate; use translate;
with Tasks; use Tasks;
with task_group_set; use task_group_set;
with event_analyzers; use event_analyzers;
with event_analyzer_set; use event_analyzer_set;
with event_analyzer_set; use event_analyzer_set.generic_event_analyzer_set;
with unbounded_strings; use unbounded_strings;
with Scheduling_Analysis; use Scheduling_Analysis;
with expressions; use expressions;
with Framework_Config; use Framework_Config;
with multiprocessor_services; use multiprocessor_services;
with time_unit_events; use time_unit_events;
use time_unit_events.time_unit_package;
with partitioning_services; use partitioning_services;
with debug; use debug;
with priority_assignment.dm; use priority_assignment.dm;
with priority_assignment.rm; use priority_assignment.rm;
with priority_assignment.audsley_opa; use priority_assignment.audsley_opa;
with priority_assignment; use priority_assignment;
with cache_set; use cache_set;
with priority_assignment.audsley_opa_crpd;
use priority_assignment.audsley_opa_crpd;
with feasibility_test; use feasibility_test;
with feasibility_test.processor_utilization;
use feasibility_test.processor_utilization;
with feasibility_test.feasibility_interval;
use feasibility_test.feasibility_interval;
with feasibility_test.periodic_task_worst_case_response_time;
use feasibility_test.periodic_task_worst_case_response_time;
with feasibility_test.transaction_worst_case_response_time;
use feasibility_test.transaction_worst_case_response_time;
with Scheduling_Analysis.extended.task_analysis;
use Scheduling_Analysis.extended.task_analysis;
with framework; use framework;
with Core_Units; use Core_Units;
use Core_Units.Core_Units_Table_Package;
with Caches; use Caches;
with cache_block_set; use cache_block_set;
with cache_access_profile_set; use cache_access_profile_set;
with Processor_Interface; use Processor_Interface;
with feasibility_test.processor_demand; use feasibility_test.processor_demand;
with xml_tag; use xml_tag;
package body call_scheduling_framework is
procedure compute_simulation_time_line
(sys : in out system;
result : in out Unbounded_String;
period : in Natural;
options : in scheduling_option;
event_to_generate : in time_unit_event_type_boolean_table;
output : in output_format := string_output)
is
begin
put_debug ("Call Compute_Simulation_Time_Line");
sort (sys.tasks, increasing_name'access);
scheduling_base_period := period;
initialize (sched.all);
build_multiprocessor_scheduling
(sys,
sched,
event_to_generate,
period,
options);
exception
when exit_statement_exception =>
result :=
result &
lb_minus &
lb_simulation_warning (Current_Language) &
Exception_Message &
unbounded_lf;
when parametric_file_error =>
result :=
result &
lb_minus &
lb_simulation_error (Current_Language) &
lb_parametric_file_error (Current_Language) &
lb_comma &
Exception_Message &
unbounded_lf;
when type_error =>
result :=
result &
lb_minus &
lb_simulation_error (Current_Language) &
lb_type_error (Current_Language) &
lb_comma &
Exception_Message &
unbounded_lf;
when statement_error =>
result :=
result &
lb_minus &
lb_simulation_error (Current_Language) &
lb_statement_error (Current_Language) &
lb_comma &
Exception_Message &
unbounded_lf;
when variable_error =>
result :=
result &
lb_minus &
lb_simulation_error (Current_Language) &
lb_variable_error (Current_Language) &
lb_comma &
Exception_Message &
unbounded_lf;
when syntax_error =>
result :=
result &
lb_minus &
lb_simulation_error (Current_Language) &
lb_syntax_error (Current_Language) &
lb_comma &
Exception_Message &
unbounded_lf;
when time_unit_package.indexed_table_full =>
result :=
result &
lb_minus &
lb_compute_scheduling_error_22 (Current_Language) &
unbounded_lf;
initialize (sched.all);
when cache_access_profile_must_be_defined =>
result :=
result &
unbounded_lf &
lb_cache_access_profile_must_be_defined (Current_Language) &
unbounded_lf;
end compute_simulation_time_line;
procedure compute_simulation_basics
(sys : in system;
result : in out Unbounded_String;
a_processor : in generic_processor_ptr;
output : in output_format := string_output)
is
check : Unbounded_String;
begin
put_debug ("Call Compute_Simulation_Basics");
if output = xml_output then
result :=
result &
start_feasibility_Test &
To_Unbounded_String (" name=""") &
lb_task_response_time_from_simulation (Current_Language) &
To_Unbounded_String (""" reference=""") &
a_processor.name &
To_Unbounded_String (""">") &
unbounded_lf;
end if;
check := empty_string;
compute_simulation_number_of_context_switch
(sys,
check,
a_processor,
output);
result := result & check;
check := empty_string;
compute_simulation_number_of_preemption
(sys,
check,
a_processor,
output);
result := result & check;
--check := empty_string;
--compute_simulation_number_of_overflow
-- (sys,
-- check,
-- a_processor,
-- output);
--result := result & check;
--check := empty_string;
--compute_simulation_number_of_underflow
-- (sys,
-- check,
-- a_processor,
-- output);
--result := result & check;
check := empty_string;
compute_simulation_response_time
(sys,
check,
a_processor,
True,
False,
False,
output);
result := result & unbounded_lf & check & unbounded_lf;
if output = xml_output then
result := result & end_feasibility_Test & unbounded_lf;
end if;
end compute_simulation_basics;
procedure compute_simulation_number_of_context_switch
(sys : in system;
result : in out Unbounded_String;
a_processor : in generic_processor_ptr;
output : in output_format := string_output)
is
nb : Natural := 0;
Nb_Str : Unbounded_String := empty_string;
begin
put_debug ("Call Compute_Simulation_Number_Of_Context_Switch");
for j in 0 .. sched.nb_entries - 1 loop
if sched.entries (j).item.name = a_processor.name then
if sched.entries (j).data.error_msg /= empty_string then
if output /= xml_output then
result :=
result & sched.entries (j).data.error_msg & unbounded_lf;
end if;
Nb_Str := empty_string;
else
nb :=
number_of_switch_context_from_simulation
(sched.entries (j).data.result);
Nb_Str := To_Unbounded_String (nb'img);
if output /= xml_output then
result :=
result &
lb_minus &
lb_number_of_context_switch (Current_Language) &
lb_colon &
nb'img &
unbounded_lf;
end if;
end if;
if output = xml_output then
result :=
result &
start_computation &
To_Unbounded_String (" name=") &
To_Unbounded_String ("""") &
lb_number_of_context_switch (Current_Language) &
To_Unbounded_String ("""") &
To_Unbounded_String (" reference=") &
To_Unbounded_String ("""") &
a_processor.name &
To_Unbounded_String ("""") &
To_Unbounded_String (" value=""") &
Nb_Str &
To_Unbounded_String (""" note=""") &
sched.entries (j).data.error_msg &
To_Unbounded_String (""" biblio=") &
To_Unbounded_String ("""""/>") &
unbounded_lf;
end if;
end if;
end loop;
end compute_simulation_number_of_context_switch;
procedure compute_simulation_number_of_preemption
(sys : in system;
result : in out Unbounded_String;
a_processor : in generic_processor_ptr;
output : in output_format := string_output)
is
nb : Natural := 0;
Nb_Str : Unbounded_String := empty_string;
begin
put_debug ("Call Compute_Simulation_Number_Of_Preemption");
for j in 0 .. sched.nb_entries - 1 loop
if sched.entries (j).item.name = a_processor.name then
if sched.entries (j).data.error_msg /= empty_string then
if output /= xml_output then
result :=
result & sched.entries (j).data.error_msg & unbounded_lf;
end if;
Nb_Str := empty_string;
else
nb :=
number_of_preemption_from_simulation
(sched.entries (j).data.result,
sys.tasks);
Nb_Str := To_Unbounded_String (nb'img);
if output /= xml_output then
result := result & sched.entries (j).data.scheduling_msg;
result :=
result &
lb_minus &
lb_number_of_preemption (Current_Language) &
lb_colon &
nb'img &
unbounded_lf;
end if;
end if;
if output = xml_output then
result :=
result &
start_computation &
To_Unbounded_String (" name=") &
To_Unbounded_String ("""") &
lb_number_of_preemption (Current_Language) &
To_Unbounded_String ("""") &
To_Unbounded_String (" reference=") &
To_Unbounded_String ("""") &
a_processor.name &
To_Unbounded_String ("""") &
To_Unbounded_String (" value=""") &
Nb_Str &
To_Unbounded_String (""" note=""") &
sched.entries (j).data.error_msg &
To_Unbounded_String (""" biblio=") &
To_Unbounded_String ("""""/>") &
unbounded_lf;
end if;
end if;
end loop;
end compute_simulation_number_of_preemption;
procedure compute_simulation_number_of_overflow
(sys : in system;
result : in out Unbounded_String;
a_processor : in generic_processor_ptr;
output : in output_format := string_output)
is
nb : Natural := 0;
begin
put_debug ("Call Compute_Simulation_Number_Of_Overflow");
for j in 0 .. sched.nb_entries - 1 loop
if sched.entries (j).item.name = a_processor.name then
if sched.entries (j).data.error_msg /= empty_string then
result :=
result & sched.entries (j).data.error_msg & unbounded_lf;
else
nb :=
number_of_overflow_from_simulation
(sched.entries (j).data.result);
if (nb > 0) then
result := result & sched.entries (j).data.scheduling_msg;
result :=
result &
lb_minus &
lb_number_of_overflow (Current_Language) &
lb_colon &
nb'img &
unbounded_lf;
end if;
end if;
end if;
end loop;
end compute_simulation_number_of_overflow;
procedure compute_simulation_number_of_underflow
(sys : in system;
result : in out Unbounded_String;
a_processor : in generic_processor_ptr;
output : in output_format := string_output)
is
nb : Natural := 0;
begin
put_debug ("Call Compute_Simulation_Number_Of_Overflow");
for j in 0 .. sched.nb_entries - 1 loop
if sched.entries (j).item.name = a_processor.name then
if sched.entries (j).data.error_msg /= empty_string then
result :=
result & sched.entries (j).data.error_msg & unbounded_lf;
else
nb :=
number_of_underflow_from_simulation
(sched.entries (j).data.result);
if (nb > 0) then
result := result & sched.entries (j).data.scheduling_msg;
result :=
result &
lb_minus &
lb_number_of_underflow (Current_Language) &
lb_colon &
nb'img &
unbounded_lf;
end if;
end if;
end if;
end loop;
end compute_simulation_number_of_underflow;
procedure compute_simulation_response_time
(sys : in system;
result : in out Unbounded_String;
a_processor : in generic_processor_ptr;
worst_case : Boolean;
best_case : Boolean;
average_case : Boolean;
output : in output_format := string_output)
is
check : Unbounded_String := empty_string;
a_task : generic_task_ptr;
my_iterator : tasks_iterator;
min : Natural := 0;
max : Natural := 0;
average : Double := 0.0;
missed : Boolean := False;
completed : Boolean := True;
has_error : Boolean := False;
has_discarded_deadline : Boolean := False;
A_Scheduler : generic_scheduler_ptr;
preemptive : Unbounded_String := empty_string;
Max_Str : Unbounded_String := empty_string;
Min_Str : Unbounded_String := empty_string;
Average_Str : Unbounded_String := empty_string;
error_str : Unbounded_String := empty_string;
begin
put_debug ("Call Compute_Simulation_Response_Time");
for j in 0 .. sched.nb_entries - 1 loop
if sched.entries (j).item.name = a_processor.name then
if sched.entries (j).data.error_msg /= empty_string then
has_error := True;
error_str := sched.entries (j).data.error_msg;
end if;
-- Check if there are discarded missed deadlines
--
for k in 0 .. sched.entries (j).data.result.nb_entries - 1 loop
if
(sched.entries (j).data.result.entries (k).data
.type_of_event =
discard_missed_deadline)
then
has_discarded_deadline := True;
end if;
end loop;
if
(get_number_of_task_from_processor
(sys.tasks,
a_processor.name) >
0) and
(not has_discarded_deadline)
then
if output /= xml_output then
result :=
lb_minus &
lb_task_response_time_from_simulation (Current_Language) &
lb_colon &
unbounded_lf;
end if;
reset_iterator (sys.tasks, my_iterator);
loop
current_element (sys.tasks, a_task, my_iterator);
check := empty_string;
if (a_processor.name = a_task.cpu_name) then
response_time_by_simulation
(a_task,
sched.entries (j).data.result,
check,
max,
min,
average);
if output /= xml_output then
result :=
result &
lb_tab4 &
a_task.name &
To_Unbounded_String (" =>");
else
result :=
result &
start_computation &
To_Unbounded_String (" name=") &
To_Unbounded_String ("""") &
Lb_Xml_Response_Time
(Current_Language) &
To_Unbounded_String ("""") &
To_Unbounded_String (" reference=") &
To_Unbounded_String ("""") &
a_task.name &
To_Unbounded_String ("""");
end if;
if output = xml_output then
if (worst_case) and (max = 0) then
Max_Str := empty_string;
Min_Str := empty_string;
Average_Str := empty_string;
else
Max_Str := To_Unbounded_String (max'img);
Min_Str := To_Unbounded_String (min'img);
Average_Str := format (average);
end if;
end if;
if worst_case then
if output /= xml_output then
result :=
result & max'img & To_Unbounded_String ("/worst ");
else
result :=
result &
To_Unbounded_String (" worst=") &
To_Unbounded_String ("""") &
Max_Str &
To_Unbounded_String ("""");
end if;
end if;
if best_case then
if output /= xml_output then
result :=
result & min'img & To_Unbounded_String ("/best ");
else
result :=
result &
To_Unbounded_String (" best=") &
To_Unbounded_String ("""") &
Min_Str &
To_Unbounded_String ("""");
end if;
end if;
if average_case then
if output /= xml_output then
result :=
result &
format (average) &
To_Unbounded_String ("/average ");
else
result :=
result &
To_Unbounded_String (" average=") &
To_Unbounded_String ("""") &
Average_Str &
To_Unbounded_String ("""");
end if;
end if;
if (worst_case) and (max = 0) then
if output /= xml_output then
result :=
result &
lb_comma &
lb_task_is_not_over_response_time_is_not_computed
(Current_Language);
else
result :=
result &
To_Unbounded_String (" note=") &
To_Unbounded_String ("""") &
lb_task_is_not_over_response_time_is_not_computed
(Current_Language) &
To_Unbounded_String ("""");
end if;
completed := False;
end if;
if output = xml_output then
result :=
result &
To_Unbounded_String (" biblio=") &
To_Unbounded_String ("""""/>") &
unbounded_lf;
else
result := result & check & unbounded_lf;
end if;
if check /= empty_string then
missed := True;
end if;
end if;
exit when is_last_element (sys.tasks, my_iterator);
next_element (sys.tasks, my_iterator);
end loop;
end if;
end if;
end loop;
-- test the feasibility
if output = xml_output then
A_Scheduler := build_a_scheduler (a_processor);
if get_preemptive (A_Scheduler.all) = "PREEMPTIVE" then
preemptive := To_Unbounded_String ("true");
else
preemptive := To_Unbounded_String ("false");
end if;
result := result & start_schedulability;
result :=
result &
To_Unbounded_String (" scheduler=""") &
get_name (A_Scheduler.all) &
To_Unbounded_String ("""") &
To_Unbounded_String (" preemptive=""") &
preemptive &
To_Unbounded_String ("""");
end if;
if not has_error then
if has_discarded_deadline then
if output /= xml_output then
result :=
result &
lb_minus &
lb_cannot_compute_wcrt_with_discard_missed_deadline
(Current_Language);
else
result :=
result &
To_Unbounded_String (" result=""false"" explanation=""") &
lb_cannot_compute_wcrt_with_discard_missed_deadline
(Current_Language) &
unbounded_lf;
end if;
elsif completed = True then
if missed = False then
if output /= xml_output then
result :=
result &
lb_minus &
lb_no_deadline_missed_in_the_computed_scheduling
(Current_Language) &
unbounded_lf;
else
result :=
result &
To_Unbounded_String (" result=""true"" explanation=""") &
lb_no_deadline_missed_in_the_computed_scheduling
(Current_Language) &
unbounded_lf;
end if;
else
if output /= xml_output then
result :=
result &
lb_minus &
lb_deadline_will_be_missed_task_are_not_schedulable
(Current_Language) &
unbounded_lf;
else
result :=
result &
To_Unbounded_String (" result=""false"" explanation=""") &
lb_deadline_will_be_missed_task_are_not_schedulable
(Current_Language) &
unbounded_lf;
end if;
end if;
else
if output /= xml_output then
result :=
result &
lb_minus &
lb_cannot_say_if_deadline_will_be_missed_in_the_computed_scheduling
(Current_Language);
else
result :=
result &
To_Unbounded_String (" result=""false"" explanation=""") &
lb_cannot_say_if_deadline_will_be_missed_in_the_computed_scheduling
(Current_Language);
end if;
end if;
if output = xml_output then
result := result & To_Unbounded_String ("""");
end if;
else
if output = xml_output then
result :=
result &
To_Unbounded_String (" result=""false"" explanation=""") &
error_str &
To_Unbounded_String ("""");
end if;
end if;
if output = xml_output then
result :=
result &
To_Unbounded_String (" biblio=") &
To_Unbounded_String ("""""/>");
end if;
end compute_simulation_response_time;
procedure compute_feasibility_interval
(sys : in system;
result : in out Unbounded_String;
a_processor : in generic_processor_ptr;
output : in output_format := string_output)
is
period_string : Unbounded_String;
free_ut_string : Unbounded_String;
period : Double := 0.0;
util : Double := 0.0;
free_ut : Double := 0.0;
validate : Boolean;
msg : Unbounded_String;
begin
put_debug ("Call Compute_Feasibility_Interval");
begin
calculate_feasibility_interval
(sys,
a_processor,
validate,
period,
msg);
exception
when Constraint_Error =>
-- A large task set with many different period values can lead to
-- a CONSTRAINT_ERROR exception due to type overflow
--
result :=
result &
To_Unbounded_String ("- ") &
Exception_Name &
" " &
Exception_Message &
unbounded_lf;
result :=
result &
lb_minus &
"Cheddar warning: Scheduling period overflow! " &
unbounded_lf;
end;
period_string := " " & format (period, 0);
if output = xml_output then
result :=
result &
start_computation &
To_Unbounded_String (" name=") &
To_Unbounded_String ("""") &
Lb_Xml_Base_Period (Current_Language) &
To_Unbounded_String ("""") &
To_Unbounded_String (" reference=") &
To_Unbounded_String ("""") &
a_processor.name &
To_Unbounded_String ("""") &
To_Unbounded_String (" value=""") &
format (period) &
To_Unbounded_String (""" biblio=""") &
msg &
To_Unbounded_String ("""");
else
result :=
result &
lb_minus &
lb_scheduling_period (Current_Language) &
period_string &
msg &
unbounded_lf;
end if;
util := processor_utilization_over_period (sys.tasks, a_processor.name);
if (a_processor.processor_type = monocore_type) then
free_ut := period * (1.0 - util);
else
free_ut :=
period *
(Double (multi_cores_processor_ptr (a_processor).cores.nb_entries) -
util);
end if;
free_ut := Double'max (0.0, free_ut);
if free_ut > Double (Natural'last) then
free_ut_string := To_Unbounded_String (Double'image (free_ut));
else
free_ut_string :=
To_Unbounded_String (Natural'image (Natural (free_ut)));
end if;
if output = xml_output then
result :=
result &
To_Unbounded_String (" unused=""") &
format (free_ut) &
To_Unbounded_String ("""/>") &
unbounded_lf;
else
result :=
result &
To_Unbounded_String ("-") &
free_ut_string &
lb_free_unit_time (Current_Language) &
unbounded_lf;
end if;
exception
when task_set.task_must_be_periodic =>
if output /= xml_output then
result :=
result &
lb_minus &
lb_compute_scheduling_error_2 (Current_Language) &
unbounded_lf;
else
result :=
result &
To_Unbounded_String (" exception=""") &
lb_compute_scheduling_error_2 (Current_Language) &
To_Unbounded_String ("""/>") &
unbounded_lf;
end if;
when task_set.task_model_error =>
if output /= xml_output then
result :=
result &
lb_minus &
lb_compute_scheduling_error_3 (Current_Language) &
unbounded_lf;
else
result :=
result &
To_Unbounded_String (" exception=""") &
lb_compute_scheduling_error_3 (Current_Language) &
To_Unbounded_String ("""/>") &
unbounded_lf;
end if;
end compute_feasibility_interval;
procedure compute_feasibility_processor_utilization_factor
(sys : in system;
result : in out Unbounded_String;
a_processor : in generic_processor_ptr;
output : in output_format := string_output)
is
util : Double;
utildi : Double;
a_scheduler : generic_scheduler_ptr;
preemptive : Unbounded_String := empty_string;
begin
put_debug ("Call Compute_Feasibility_Processor_Utilization_Factor");
-- Compute feasibility interval
--
if output /= xml_output then
result :=
result &
lb_feasibility_number1 (Current_Language) &
unbounded_lf &
unbounded_lf;
end if;
compute_feasibility_interval (sys, result, a_processor, output);
if output = xml_output then
result :=
result &
start_computation &
To_Unbounded_String (" name=") &
To_Unbounded_String ("""") &
Lb_Xml_Processor_Utilization_Factor_Deadline (Current_Language) &
To_Unbounded_String ("""") &
To_Unbounded_String (" reference=") &
To_Unbounded_String ("""") &
a_processor.name &
To_Unbounded_String ("""");
end if;
-- Compute number of cores of the processor
--
if output /= xml_output then
if (a_processor.processor_type = monocore_type) then
result :=
result &
lb_minus &
lb_processor_has_number_of_cores (Current_Language) &
To_Unbounded_String (" 1. ") &
unbounded_lf;
else
result :=
result &
lb_minus &
lb_processor_has_number_of_cores (Current_Language) &
To_Unbounded_String
(" " &
multi_cores_processor_ptr (a_processor).cores.nb_entries'img &
". ") &
unbounded_lf;
end if;
end if;
-- Compute processor utilization faction over deadline
--
begin
utildi :=
processor_utilization_over_deadline (sys.tasks, a_processor.name);
if output = xml_output then
result :=
result &
To_Unbounded_String (" value=""") &
format (utildi) &
To_Unbounded_String (""" biblio=") &
To_Unbounded_String ("""[1], page 6""") &
To_Unbounded_String ("/>") &
unbounded_lf;
else
result :=
result &
lb_minus &
lb_utilization_with_deadline (Current_Language) &
format (utildi) &
To_Unbounded_String (" (") &
lb_see (Current_Language) &
To_Unbounded_String ("[1], page 6). ") &
unbounded_lf;
end if;
exception
when task_set.task_must_be_periodic =>
if output /= xml_output then
result :=
result &
lb_minus &
lb_compute_scheduling_error_9 (Current_Language) &
unbounded_lf;
else
result :=
result & To_Unbounded_String (" value=""NA"" explanation=""");
result :=
result & lb_compute_scheduling_error_9 (Current_Language);
result :=
result &
To_Unbounded_String (""" biblio=""") &
To_Unbounded_String ("""/>") &
unbounded_lf;
end if;
when task_set.task_model_error =>
if output /= xml_output then
result :=
result &
lb_minus &
lb_compute_scheduling_error_10 (Current_Language) &
unbounded_lf;
else
result :=
result & To_Unbounded_String (" value=""NA"" explanation=""");
result :=
result & lb_compute_scheduling_error_10 (Current_Language);
result :=
result &
To_Unbounded_String (""" biblio=""") &
To_Unbounded_String ("""/>") &
unbounded_lf;
end if;
when deadline_error =>
if output /= xml_output then
result :=
result &
lb_minus &
lb_compute_scheduling_error_21 (Current_Language) &
unbounded_lf;
else
result :=
result & To_Unbounded_String (" value=""NA"" explanation=""");
result :=
result & lb_compute_scheduling_error_10 (Current_Language);
result :=
result &
To_Unbounded_String (""" biblio=""") &
To_Unbounded_String ("""/>") &
unbounded_lf;
end if;
end;
if output = xml_output then
result :=
result &
start_computation &
To_Unbounded_String (" name=") &
To_Unbounded_String ("""") &
Lb_Xml_Processor_Utilization_Factor_Period (Current_Language) &
To_Unbounded_String ("""") &
To_Unbounded_String (" reference=") &
To_Unbounded_String ("""") &
a_processor.name &
To_Unbounded_String ("""");
end if;
-- Compute processor utilization factor over period
--
begin
util :=
processor_utilization_over_period (sys.tasks, a_processor.name);
if output = xml_output then
result :=
result &
To_Unbounded_String (" value=""") &
format (util) &
To_Unbounded_String (""" biblio=") &
To_Unbounded_String ("""[1], page 6""") &
To_Unbounded_String ("/>") &
unbounded_lf;
else
result :=
result &
lb_minus &
lb_utilization_with_period (Current_Language) &
format (util) &
To_Unbounded_String (" (") &
lb_see (Current_Language) &
To_Unbounded_String ("[1], page 6). ") &
unbounded_lf;
end if;
exception
when task_set.task_must_be_periodic =>
if output /= xml_output then
result :=
result &
lb_minus &
lb_compute_scheduling_error_9 (Current_Language) &
unbounded_lf;
else
result := result & To_Unbounded_String (" value=""NA"" explanation=""");
result := result & lb_compute_scheduling_error_9 (current_language);
result := result & To_Unbounded_String (""" biblio=""") & To_Unbounded_String ("""/>") & unbounded_lf;
end if;
when task_set.task_model_error =>
if output /= xml_output then
result :=
result &
lb_minus &
lb_compute_scheduling_error_10 (Current_Language) &
unbounded_lf;
else
result := result & To_Unbounded_String (" value=""NA"" explanation=""");
result := result & lb_compute_scheduling_error_10 (Current_Language);
result := result & To_Unbounded_String (""" biblio=""") & To_Unbounded_String ("""/>") &
unbounded_lf;
end if;
end;
-- In the case of a partitionned multiprocessor with cores
-- compute & display the core unit utilization factor
--
if (a_processor.processor_type /= monocore_type) and
(a_processor.migration_type = no_migration_type)
then
if output /= xml_output then
result :=
result &
lb_minus &
lb_core_utilization (Current_Language) &
To_Unbounded_String (" (") &
lb_see (Current_Language) &
To_Unbounded_String ("[1], page 6) ") &
unbounded_lf;
end if;
for i in
0 .. multi_cores_processor_ptr (a_processor).cores.nb_entries - 1
loop
-- Compute core unit utilization faction over deadline
--
begin
if output = xml_output then
result :=
result &
start_computation &
To_Unbounded_String (" name=") &
To_Unbounded_String ("""") &
Lb_Xml_Core_Utilization_Factor_Deadline (Current_Language) &
To_Unbounded_String ("""") &
To_Unbounded_String (" reference=") &
To_Unbounded_String ("""") &
Multi_Cores_Processor_ptr(a_processor).cores.entries(i).name &
To_Unbounded_String ("""");
end if;
utildi :=
processor_utilization_over_deadline
(sys.tasks,
a_processor.name,
multi_cores_processor_ptr (a_processor).cores.entries (i)
.name);
if output /= xml_output then
result :=
result &
lb_tab5 & lb_minus &
lb_core_utilization_with_deadline (Current_Language) &
multi_cores_processor_ptr (a_processor).cores.entries (i)
.name &
" : " &
format (utildi) &
To_Unbounded_String (".") &
unbounded_lf;
else
result :=
result &
To_Unbounded_String (" value=""") &
format (utildi) &
To_Unbounded_String (""" biblio=") &
To_Unbounded_String ("""[1], page 6""") &
To_Unbounded_String ("/>") &
unbounded_lf;
end if;
exception
when task_set.task_must_be_periodic =>
if output /= xml_output then
result :=
result &
lb_minus &
lb_compute_scheduling_error_9 (Current_Language) &
unbounded_lf;
else
result := result & To_Unbounded_String (" value=""NA"" explanation=""");
result := result & lb_compute_scheduling_error_9 (Current_Language);
result := result & To_Unbounded_String (""" biblio=""") & To_Unbounded_String ("""/>") &
unbounded_lf;
end if;
when task_set.task_model_error =>
if output /= xml_output then
result :=
result &
lb_minus &
lb_compute_scheduling_error_10 (Current_Language) &
unbounded_lf;
else
result := result & To_Unbounded_String (" value=""NA"" explanation=""");
result := result & lb_compute_scheduling_error_10 (Current_Language);
result := result & To_Unbounded_String (""" biblio=""") & To_Unbounded_String ("""/>") &
unbounded_lf;
end if;
when deadline_error =>
if output /= xml_output then
result :=
result &
lb_minus &
lb_compute_scheduling_error_21 (Current_Language) &
unbounded_lf;
else
result := result & To_Unbounded_String (" value=""NA"" explanation=""");
result := result & lb_compute_scheduling_error_21 (Current_Language);
result := result & To_Unbounded_String (""" biblio=""") & To_Unbounded_String ("""/>") &
unbounded_lf;
end if;
end;
-- Compute core unit utilization factor over period
--
begin
if output = xml_output then
result :=
result &
start_computation &
To_Unbounded_String (" name=") &
To_Unbounded_String ("""") &
Lb_Xml_Core_Utilization_Factor_Period (Current_Language) &
To_Unbounded_String ("""") &
To_Unbounded_String (" reference=") &
To_Unbounded_String ("""") &
Multi_Cores_Processor_ptr(a_processor).cores.entries(i).name &
To_Unbounded_String ("""");
end if;
util :=
processor_utilization_over_period
(sys.tasks,
a_processor.name,
multi_cores_processor_ptr (a_processor).cores.entries (i)
.name);
if output /= xml_output then
result :=
result &
lb_tab5 & lb_minus &
lb_core_utilization_with_period (Current_Language) &
multi_cores_processor_ptr (a_processor).cores.entries (i)
.name &
" : " &
format (util) &
To_Unbounded_String (".") &
unbounded_lf;
else
result :=
result &
To_Unbounded_String (" value=""") &
format (util) &
To_Unbounded_String (""" biblio=") &
To_Unbounded_String ("""[1], page 6""") &
To_Unbounded_String ("/>") &
unbounded_lf;
end if;
exception
when task_set.task_must_be_periodic =>
if output /= xml_output then
result :=
result &
lb_minus &
lb_compute_scheduling_error_9 (Current_Language) &
unbounded_lf;
else
result := result & To_Unbounded_String (" value=""NA"" explanation=""");
result := result & lb_compute_scheduling_error_9 (Current_Language);
result := result & To_Unbounded_String (""" biblio=""") & To_Unbounded_String ("""/>") &
unbounded_lf;
end if;
when task_set.task_model_error =>
if output /= xml_output then
result :=
result &
lb_minus &
lb_compute_scheduling_error_10 (Current_Language) &
unbounded_lf;
else
result := result & To_Unbounded_String (" value=""NA"" explanation=""");
result := result & lb_compute_scheduling_error_10 (Current_Language);
result := result & To_Unbounded_String (""" biblio=""") & To_Unbounded_String ("""/>") &
unbounded_lf;
end if;
end;
end loop;
end if;
-- Compute feasibility test on the Processor utilization bound
--
if (a_processor.processor_type = monocore_type) then
begin
a_scheduler := build_a_scheduler (a_processor);
if output = xml_output then
result := result & start_schedulability;
if get_preemptive (a_scheduler.all) = "PREEMPTIVE" then
preemptive := To_Unbounded_String ("true");
else
preemptive := To_Unbounded_String ("false");
end if;
result :=
result &
To_Unbounded_String (" scheduler=""") &
get_name (a_scheduler.all) &
To_Unbounded_String ("""") &
To_Unbounded_String (" preemptive=""") &
preemptive &
To_Unbounded_String ("""");
end if;
utilization_factor_feasibility_test
(a_scheduler,
sys.tasks,
a_processor.name,
result,
output);
if output = xml_output then
result := result & To_Unbounded_String ("/>") & unbounded_lf;
end if;
free (a_scheduler);
exception
when task_set.task_must_be_periodic =>
if output /= xml_output then
result :=
result &
lb_minus &
lb_compute_scheduling_error_9 (Current_Language) &
unbounded_lf;
else
result :=
result &
To_Unbounded_String (" result=""false"" explanation=""");
result :=
result & lb_compute_scheduling_error_9 (current_language);
result :=
result &
To_Unbounded_String (""" biblio=""") &
To_Unbounded_String ("""/>") &
unbounded_lf;
end if;
when task_set.task_model_error =>
if output /= xml_output then
result :=
result &
lb_minus &
lb_compute_scheduling_error_10 (Current_Language) &
unbounded_lf;
else
result :=
result &
To_Unbounded_String (" result=""false"" explanation=""");
result :=
result & lb_compute_scheduling_error_10 (current_language);
result :=
result &
To_Unbounded_String (""" biblio=""") &
To_Unbounded_String ("""/>") &
unbounded_lf;
end if;
when deadline_error =>
if output /= xml_output then
result :=
result &
lb_minus &
lb_compute_scheduling_error_21 (Current_Language) &
unbounded_lf;
else
result :=
result &
To_Unbounded_String (" result=""false"" explanation=""");
result :=
result & lb_compute_scheduling_error_21 (current_language);
result :=
result &
To_Unbounded_String (""" biblio=""") &
To_Unbounded_String ("""/>") &
unbounded_lf;
end if;
when task_set.start_time_error =>
if output /= xml_output then
result :=
result &
lb_minus &
lb_compute_scheduling_error_23 (Current_Language) &
unbounded_lf;
else
result :=
result &
To_Unbounded_String (" result=""false"" explanation=""");
result :=
result & lb_compute_scheduling_error_23 (current_language);
result :=
result &
To_Unbounded_String (""" biblio=""") &
To_Unbounded_String ("""/>") &
unbounded_lf;
end if;
when task_set.offset_error =>
if output /= xml_output then
result :=
result &
lb_minus &
lb_compute_scheduling_error_24 (Current_Language) &
unbounded_lf;
else
result :=
result &
To_Unbounded_String (" result=""false"" explanation=""");
result :=
result & lb_compute_scheduling_error_24 (current_language);
result :=
result &
To_Unbounded_String (""" biblio=""") &
To_Unbounded_String ("""/>") &
unbounded_lf;
end if;
end;
else
result := result & start_schedulability;
result :=
result &
To_Unbounded_String (" result=""notImplemented"" explanation=""The feasibility test for processor utilization is not implemented for the multicore case");
result :=
result &
To_Unbounded_String (""" biblio=""") &
To_Unbounded_String ("""/>") &
unbounded_lf;
end if;
end compute_feasibility_processor_utilization_factor;
procedure compute_feasibility_test_by_name
(sys : in system;
result : in out Unbounded_String;
a_processor : in generic_processor_ptr;
test_name : Unbounded_String;
output : in output_format := string_output)
is
begin
put_debug ("Call Compute_Feasibility_Test_By_Name");
result := result & unbounded_lf;
end compute_feasibility_test_by_name;
procedure compute_feasibility_response_time
(sys : in out system;
result : in out Unbounded_String;
a_transaction : in transaction_wcrt_type;
wcrt_with_memory_interferences : in memory_interference_computation_approach_type :=
no_memory_interference;
with_crpd : in crpd_computation_approach_type := no_crpd;
a_processor : in generic_processor_ptr;
output : in output_format := string_output)
is
rt : response_time_table;
msg : Unbounded_String := empty_string;
missed : Boolean := False;
a_scheduler : generic_scheduler_ptr;
preemptive : Unbounded_String := empty_string;
begin
put_debug ("Call Compute_Feasibility_Response_Time");
if output /= xml_output then
result :=
result &
unbounded_lf &
lb_feasibility_number2 (Current_Language) &
unbounded_lf &
unbounded_lf;
end if;
case a_transaction is
when periodic =>
a_scheduler := build_a_scheduler (a_processor);
compute_response_time
(a_scheduler,
sys,
a_processor.name,
msg,
rt,
wcrt_with_memory_interferences,
with_crpd);
free (a_scheduler);
when tindell =>
tindell_compute_offset_response_time
(sys.task_groups,
a_processor.name,
msg,
rt);
when audsley =>
audsley_compute_offset_response_time
(sys.task_groups,
a_processor.name,
msg,
rt);
when palencia =>
palencia_compute_offset_response_time
(sys.task_groups,
a_processor.name,
msg,
rt);
when wcdops_plus =>
wcdops_plus (sys, msg, rt, False);
when wcdops_plus_nim =>
wcdops_plus_nimp (sys, msg, rt, False);
end case;
if output /= xml_output then
result :=
result &
lb_minus &
lb_worst_case_task_response_time (Current_Language) &
lb_colon &
msg &
unbounded_lf;
end if;
for i in
0 ..
response_time_range
(get_number_of_task_from_processor
(sys.tasks,
a_processor.name) -
1)
loop
if (rt.entries (i).item /= null) then
if output /= xml_output then
result :=
result &
lb_tab4 &
rt.entries (i).item.name &
To_Unbounded_String (" =>") &
Integer'image (Integer (rt.entries (i).data));
else
result :=
result &
start_computation &
To_Unbounded_String (" name=") &
To_Unbounded_String ("""") &
Lb_Xml_Response_Time (Current_Language) &
To_Unbounded_String ("""") &
To_Unbounded_String (" reference=") &
To_Unbounded_String ("""") &
rt.entries (i).item.name &
To_Unbounded_String ("""") &
To_Unbounded_String (" value=""") &
format (rt.entries (i).data) &
To_Unbounded_String (""" biblio=") &
To_Unbounded_String ("""""/>");
end if;
if
(Natural (rt.entries (i).data) > rt.entries (i).item.deadline)
then
if output /= xml_output then
result :=
result &
lb_comma &
lb_check_deadline (Current_Language) &
rt.entries (i).item.deadline'img &
To_Unbounded_String (")");
end if;
missed := True;
end if;
result := result & unbounded_lf;
end if;
end loop;
if output = xml_output then
a_scheduler := build_a_scheduler (a_processor);
if get_preemptive (a_scheduler.all) = "PREEMPTIVE" then
preemptive := To_Unbounded_String ("true");
else
preemptive := To_Unbounded_String ("false");
end if;
result :=
result &
start_schedulability &
To_Unbounded_String (" scheduler=""") &
get_name (a_scheduler.all) &
To_Unbounded_String ("""") &
To_Unbounded_String (" preemptive=""") &
preemptive &
To_Unbounded_String ("""");
end if;
if missed = False then
if output /= xml_output then
result :=
result &
lb_minus &
lb_no_deadline_will_be_missed_task_are_schedulable
(Current_Language);
else
result :=
result &
To_Unbounded_String (" result=""true""") &
To_Unbounded_String (" explanation=""") &
lb_no_deadline_will_be_missed_task_are_schedulable
(Current_Language) &
To_Unbounded_String ("""");
end if;
else
if output /= xml_output then
result :=
result &
lb_minus &
lb_deadline_will_be_missed_task_are_not_schedulable
(Current_Language);
else
result :=
result &
To_Unbounded_String (" result=""false""") &
To_Unbounded_String (" explanation=""") &
lb_deadline_will_be_missed_task_are_not_schedulable
(Current_Language) &
To_Unbounded_String ("""");
end if;
end if;
if output /= xml_output then
result :=
result & unbounded_lf & unbounded_lf;
else
result :=
result & To_Unbounded_String (" bilbio=""""/>") & unbounded_lf;
end if;
exception
when task_set.task_must_have_period_equal_to_deadline =>
if output /= xml_output then
result :=
result &
lb_minus &
lb_compute_scheduling_error_4 (Current_Language) &
unbounded_lf;
else
result :=
result &
start_schedulability &
To_Unbounded_String (" scheduler=""""") &
To_Unbounded_String (" preemptive=""""") &
To_Unbounded_String (" result=""false""") &
To_Unbounded_String (" explanation=""") &
lb_compute_scheduling_error_4 (Current_Language) &
To_Unbounded_String (""" bilbio=""""/>") &
unbounded_lf;
end if;
when task_set.task_must_be_periodic =>
if output /= xml_output then
result :=
result &
lb_minus &
lb_compute_scheduling_error_5 (Current_Language) &
unbounded_lf;
else
result :=
result &
start_schedulability &
To_Unbounded_String (" scheduler=""""") &
To_Unbounded_String (" preemptive=""""") &
To_Unbounded_String (" result=""false""") &
To_Unbounded_String (" explanation=""") &
lb_compute_scheduling_error_5 (Current_Language) &
To_Unbounded_String (""" bilbio=""""/>") &
unbounded_lf;
end if;
when task_set.task_model_error =>
if output /= xml_output then
result :=
result &
lb_minus &
lb_compute_scheduling_error_6 (Current_Language) &
unbounded_lf;
else
result :=
result &
start_schedulability &
To_Unbounded_String (" scheduler=""""") &
To_Unbounded_String (" preemptive=""""") &
To_Unbounded_String (" result=""false""") &
To_Unbounded_String (" explanation=""") &
lb_compute_scheduling_error_6 (Current_Language) &
To_Unbounded_String (""" bilbio=""""/>") &
unbounded_lf;
end if;
when processor_utilization_exceeded =>
if output /= xml_output then
result :=
result &
lb_minus &
lb_compute_scheduling_error_7 (Current_Language) &
unbounded_lf;
else
result :=
result &
start_schedulability &
To_Unbounded_String (" scheduler=""""") &
To_Unbounded_String (" preemptive=""""") &
To_Unbounded_String (" result=""false""") &
To_Unbounded_String (" explanation=""") &
lb_compute_scheduling_error_7 (Current_Language) &
To_Unbounded_String (""" bilbio=""""/>") &
unbounded_lf;
end if;
when task_set.start_time_error =>
if output /= xml_output then
result :=
result &
lb_minus &
lb_compute_scheduling_error_12 (Current_Language) &
unbounded_lf;
else
result :=
result &
start_schedulability &
To_Unbounded_String (" scheduler=""""") &
To_Unbounded_String (" preemptive=""""") &
To_Unbounded_String (" result=""false""") &
To_Unbounded_String (" explanation=""") &
lb_compute_scheduling_error_12 (Current_Language) &
To_Unbounded_String (""" bilbio=""""/>") &
unbounded_lf;
end if;
when task_set.offset_error =>
if output /= xml_output then
result :=
result &
lb_minus &
lb_compute_scheduling_error_13 (Current_Language) &
unbounded_lf;
else
result :=
result &
start_schedulability &
To_Unbounded_String (" scheduler=""""") &
To_Unbounded_String (" preemptive=""""") &
To_Unbounded_String (" result=""false""") &
To_Unbounded_String (" explanation=""") &
lb_compute_scheduling_error_13 (Current_Language) &
To_Unbounded_String (""" bilbio=""""/>") &
unbounded_lf;
end if;
when invalid_scheduler =>
if output /= xml_output then
result :=
result &
lb_minus &
lb_compute_scheduling_error_18 (Current_Language) &
unbounded_lf;
else
result :=
result &
start_schedulability &
To_Unbounded_String (" scheduler=""""") &
To_Unbounded_String (" preemptive=""""") &
To_Unbounded_String (" result=""false""") &
To_Unbounded_String (" explanation=""") &
lb_compute_scheduling_error_18 (Current_Language) &
To_Unbounded_String (""" bilbio=""""/>") &
unbounded_lf;
end if;
when computation_time_exceeded =>
if output /= xml_output then
result :=
result &
lb_minus &
lb_computation_time_exceeded (Current_Language) &
unbounded_lf;
else
result :=
result &
start_schedulability &
To_Unbounded_String (" scheduler=""""") &
To_Unbounded_String (" preemptive=""""") &
To_Unbounded_String (" result=""false""") &
To_Unbounded_String (" explanation=""") &
lb_computation_time_exceeded (Current_Language) &
To_Unbounded_String (""" bilbio=""""/>") &
unbounded_lf;
end if;
when transaction_error =>
if output /= xml_output then
result :=
result &
lb_minus &
lb_compute_scheduling_error_25 (Current_Language) &
unbounded_lf;
else
result :=
result &
start_schedulability &
To_Unbounded_String (" scheduler=""""") &
To_Unbounded_String (" preemptive=""""") &
To_Unbounded_String (" result=""false""") &
To_Unbounded_String (" explanation=""") &
lb_compute_scheduling_error_25 (Current_Language) &
To_Unbounded_String (""" bilbio=""""/>") &
unbounded_lf;
end if;
when task_set.generic_task_set.empty_set =>
if output /= xml_output then
result :=
result &
lb_minus &
lb_compute_scheduling_error_26 (Current_Language) &
unbounded_lf;
else
result :=
result &
start_schedulability &
To_Unbounded_String (" scheduler=""""") &
To_Unbounded_String (" preemptive=""""") &
To_Unbounded_String (" result=""false""") &
To_Unbounded_String (" explanation=""") &
lb_compute_scheduling_error_26 (Current_Language) &
To_Unbounded_String (""" bilbio=""""/>") &
unbounded_lf;
end if;
when cache_access_profile_must_be_defined =>
if output /= xml_output then
result :=
result &
lb_cache_access_profile_must_be_defined (Current_Language) &
unbounded_lf;
else
result :=
result &
start_schedulability &
To_Unbounded_String (" scheduler=""""") &
To_Unbounded_String (" preemptive=""""") &
To_Unbounded_String (" result=""false""") &
To_Unbounded_String (" explanation=""") &
lb_cache_access_profile_must_be_defined (Current_Language) &
To_Unbounded_String (""" bilbio=""""/>") &
unbounded_lf;
end if;
when cache_access_profile_must_be_defined_for_all_tasks =>
if output /= xml_output then
result :=
result &
lb_cache_access_profile_must_be_defined (Current_Language) &
unbounded_lf;
else
result :=
result &
start_schedulability &
To_Unbounded_String (" scheduler=""""") &
To_Unbounded_String (" preemptive=""""") &
To_Unbounded_String (" result=""false""") &
To_Unbounded_String (" explanation=""") &
lb_cache_access_profile_must_be_defined (Current_Language) &
To_Unbounded_String (""" bilbio=""""/>") &
unbounded_lf;
end if;
end compute_feasibility_response_time;
procedure set_priorities
(sys : in out system;
result : in out Unbounded_String;
a_processor : in generic_processor_ptr;
a_scheduler : in framework_statement_type;
output : in output_format := string_output)
is
ok : Boolean := True;
error_msg : Unbounded_String;
a_task : generic_task_ptr;
my_task_iterator : tasks_iterator;
begin
put_debug ("Call Set_Priorities");
begin
if
(a_scheduler =
scheduling_set_priorities_according_to_rate_monotonic)
then
set_priority_according_to_rm (sys.tasks, a_processor.name);
elsif
(a_scheduler =
scheduling_set_priorities_according_to_deadline_monotonic)
then
set_priority_according_to_dm (sys.tasks, a_processor.name);
elsif
(a_scheduler = scheduling_set_priorities_according_to_audsley_opa)
then
set_priority_according_to_audsley_opa
(sys.tasks,
a_processor.name);
elsif
(a_scheduler =
scheduling_set_priorities_according_to_opa_crpd_pt_simplified)
then
set_priority_according_to_cpa
(sys.tasks,
sys.cache_access_profiles,
pt_simplified,
a_processor.name);
elsif
(a_scheduler = scheduling_set_priorities_according_to_opa_crpd_pt)
then
set_priority_according_to_cpa
(sys.tasks,
sys.cache_access_profiles,
pt_binomial_coefficient,
a_processor.name);
elsif
(a_scheduler = scheduling_set_priorities_according_to_opa_crpd_tree)
then
set_priority_according_to_cpa
(sys.tasks,
sys.cache_access_profiles,
tree,
a_processor.name);
end if;
exception
when task_set.task_must_be_periodic =>
ok := False;
error_msg := lb_minus & lb_priorities_error1 (Current_Language);
when generic_task_set.empty_set =>
ok := False;
error_msg := lb_minus & lb_priorities_error2 (Current_Language);
when no_feasible_priority_assignment_exception =>
ok := False;
error_msg := lb_minus & lb_priorities_error_opa (Current_Language);
when no_feasible_priority_assignment_with_crpd_exception =>
ok := False;
error_msg := lb_priorities_error_opa_crpd (Current_Language);
when offset_must_be_defined =>
ok := False;
error_msg := lb_minus & lb_offset_must_be_defined_for_opa (Current_Language);
when cache_access_profile_not_found =>
ok := False;
error_msg :=
lb_minus &
lb_cache_access_profile_must_be_defined_for_opa
(Current_Language);
when cache_access_profile_must_be_defined =>
ok := False;
error_msg :=
lb_minus &
lb_cache_access_profile_must_be_defined_for_opa
(Current_Language);
end;
if ok then
if output /= xml_output then
if
(a_scheduler =
scheduling_set_priorities_according_to_rate_monotonic)
then
result :=
result &
lb_set_priorities_rm (Current_Language);
end if;
if
(a_scheduler =
scheduling_set_priorities_according_to_deadline_monotonic)
then
result :=
result &
lb_set_priorities_dm (Current_Language);
end if;
if
(a_scheduler = scheduling_set_priorities_according_to_audsley_opa)
then
result :=
result &
lb_set_priorities_audsley_opa (Current_Language);
end if;
if
(a_scheduler = scheduling_set_priorities_according_to_opa_crpd_pt)
then
result :=
result &
lb_set_priorities_opa_crpd_pt (Current_Language);
end if;
if
(a_scheduler =
scheduling_set_priorities_according_to_opa_crpd_pt_simplified)
then
result :=
result &
lb_set_priorities_opa_crpd_pt_simplified (Current_Language);
end if;
if
(a_scheduler = scheduling_set_priorities_according_to_opa_crpd_tree)
then
result :=
result &
lb_set_priorities_opa_crpd_tree (Current_Language);
end if;
result :=
result &
unbounded_lf &
lb_minus &
lb_priorities (Current_Language);
end if;
reset_iterator (sys.tasks, my_task_iterator);
loop
current_element (sys.tasks, a_task, my_task_iterator);
if (a_task.cpu_name = a_processor.name) then
if output /= xml_output then
result :=
result &
unbounded_lf &
lb_tab4 &
a_task.name &
To_Unbounded_String (" =>") &
To_Unbounded_String (a_task.priority'img);
else
result :=
result &
start_computation &
To_Unbounded_String (" name=") &
To_Unbounded_String ("""");
if (a_scheduler = scheduling_set_priorities_according_to_rate_monotonic) then
result := result & lb_set_priorities_rm (Current_Language);
elsif (a_scheduler = scheduling_set_priorities_according_to_deadline_monotonic) then
result := result & lb_set_priorities_dm (Current_Language);
elsif (a_scheduler = scheduling_set_priorities_according_to_audsley_opa) then
result := result & lb_set_priorities_audsley_opa (Current_Language);
elsif (a_scheduler = scheduling_set_priorities_according_to_opa_crpd_pt) then
result := result & lb_set_priorities_opa_crpd_pt (Current_Language);
elsif (a_scheduler = scheduling_set_priorities_according_to_opa_crpd_pt_simplified) then
result := result & lb_set_priorities_opa_crpd_pt_simplified (Current_Language);
elsif (a_scheduler = scheduling_set_priorities_according_to_opa_crpd_tree) then
result := result & lb_set_priorities_opa_crpd_tree (Current_Language);
else
result := result & Lb_Xml_Unknown_Sched (Current_Language);
end if;
result :=
result &
To_Unbounded_String ("""") &
To_Unbounded_String (" reference=") &
To_Unbounded_String ("""") &
a_task.name &
To_Unbounded_String ("""") &
To_Unbounded_String (" value=""") &
To_Unbounded_String (a_task.priority'img) &
To_Unbounded_String (""" biblio=") &
To_Unbounded_String ("""""/>") &
unbounded_lf;
end if;
end if;
exit when is_last_element (sys.tasks, my_task_iterator);
next_element (sys.tasks, my_task_iterator);
end loop;
if output /= xml_output then -- TODO JLE : not sure it is still needed
result :=
result & unbounded_lf & unbounded_lf;
end if;
else
if output /= xml_output then
result := result & error_msg;
else
result :=
result &
To_Unbounded_String ("") &
unbounded_lf;
result := result & end_feasibility_Test;
end if;
end if;
end set_priorities;
procedure run_user_defined_event_handlers
(sys : in system;
result : in out Unbounded_String;
output : in output_format := string_output)
is
msg : Unbounded_String;
my_iterator : event_analyzers_iterator;
an_event_analyzer : event_analyzer_ptr;
begin
put_debug ("Call Run_User_Defined_Event_Handlers");
if (get_number_of_elements (sys.event_analyzers) > 0) then
reset_iterator (sys.event_analyzers, my_iterator);
loop
current_element
(sys.event_analyzers,
an_event_analyzer,
my_iterator);
-- Run an event analyzer
---
begin
msg := empty_string;
result := result & unbounded_lf & unbounded_lf;
result :=
result &
lb_minus &
lb_event_analyzer_name (Current_Language) &
lb_colon &
an_event_analyzer.event_analyzer_source_file_name &
unbounded_lf &
unbounded_lf;
run_an_event_analyzer (sys, sched, an_event_analyzer, msg);
result := result & msg;
result := result & unbounded_lf & unbounded_lf;
exception
when parametric_file_error =>
result :=
result &
lb_minus &
lb_simulation_error (Current_Language) &
lb_parametric_file_error (Current_Language) &
lb_comma &
Exception_Message &
unbounded_lf;
when type_error =>
result :=
result &
lb_minus &
lb_simulation_error (Current_Language) &
lb_type_error (Current_Language) &
lb_comma &
Exception_Message &
unbounded_lf;
when statement_error =>
result :=
result &
lb_minus &
lb_simulation_error (Current_Language) &
lb_statement_error (Current_Language) &
lb_comma &
Exception_Message &
unbounded_lf;
when variable_error =>
result :=
result &
lb_minus &
lb_simulation_error (Current_Language) &
lb_variable_error (Current_Language) &
lb_comma &
Exception_Message &
unbounded_lf;
when syntax_error =>
result :=
result &
lb_minus &
lb_simulation_error (Current_Language) &
lb_syntax_error (Current_Language) &
lb_comma &
Exception_Message &
unbounded_lf;
end;
exit when is_last_element (sys.event_analyzers, my_iterator);
next_element (sys.event_analyzers, my_iterator);
end loop;
end if;
end run_user_defined_event_handlers;
procedure partionning_tasks
(sys : in out system;
result : in out Unbounded_String;
a_parition_rule : in partioning_type;
output : in output_format := string_output)
is
partitionned_task_set : tasks_set;
a_task : generic_task_ptr;
my_task_iterator : tasks_iterator;
msg : Unbounded_String := empty_string;
a_processor : generic_processor_ptr;
a_core_processor_name : Unbounded_String;
begin
put_debug ("Call Partionning_Tasks");
case a_parition_rule is
when general_task =>
partition_general_task
(sys.processors,
sys.tasks,
msg,
partitionned_task_set);
when best_fit =>
partition_best_fit
(sys.processors,
sys.tasks,
msg,
partitionned_task_set);
when next_fit =>
partition_next_fit
(sys.processors,
sys.tasks,
msg,
partitionned_task_set);
when first_fit =>
partition_first_fit
(sys.processors,
sys.tasks,
msg,
partitionned_task_set);
when small_task =>
partition_small_task
(sys.processors,
sys.tasks,
msg,
partitionned_task_set);
end case;
if output /= xml_output then
result :=
result &
lb_minus &
lb_partitioning_result (Current_Language) &
msg &
lb_colon &
unbounded_lf;
end if;
sys.tasks := partitionned_task_set;
reset_iterator (sys.tasks, my_task_iterator);
loop
current_element (sys.tasks, a_task, my_task_iterator);
if output /= xml_output then
result :=
result &
unbounded_lf &
lb_tab4 &
a_task.name &
To_Unbounded_String (" =>") &
a_task.cpu_name;
else
-- use to match aadl inspector parsing (a core field can be added)
a_processor := search_processor(sys.processors, a_task.cpu_name);
if a_processor.processor_type = monocore_type then
a_core_processor_name := a_task.cpu_name;
else
a_core_processor_name := a_task.core_name;
end if;
result :=
result &
lb_tab4 &
To_Unbounded_String ("") &
unbounded_lf;
end if;
exit when is_last_element (sys.tasks, my_task_iterator);
next_element (sys.tasks, my_task_iterator);
end loop;
if output /= xml_output then -- TODO JLE : not sure if it is still needed
result := result & unbounded_lf & unbounded_lf;
end if;
exception
when processors_should_have_the_same_scheduler =>
if output /= xml_output then
result := result & lb_minus & lb_partition_error1 (Current_Language);
else
result :=
result &
To_Unbounded_String ("");
end if;
when no_such_processors =>
if output /= xml_output then
result := result & lb_minus & lb_partition_error2 (Current_Language);
else
result :=
result &
To_Unbounded_String ("");
end if;
when invalid_scheduler_multiprocessors =>
if output /= xml_output then
result := result & lb_minus & lb_partition_error3 (Current_Language);
else
result :=
result &
To_Unbounded_String ("");
end if;
when task_set.task_must_be_periodic =>
if output /= xml_output then
result := result & lb_minus & lb_partition_error4 (Current_Language);
else
result :=
result &
To_Unbounded_String ("");
end if;
end partionning_tasks;
procedure compute_feasibility_basics
(sys : in out system;
result : in out Unbounded_String;
a_processor : in generic_processor_ptr;
output : in output_format := string_output)
is
begin
put_debug ("Call Compute_Feasibility_Basics");
if output = xml_output then
result :=
result &
start_feasibility_Test &
To_Unbounded_String (" name=""") &
Lb_Xml_Processor_Utilization_Factor (Current_Language) &
To_Unbounded_String (""" reference=""") &
a_processor.name &
To_Unbounded_String (""">") &
unbounded_lf;
end if;
compute_feasibility_processor_utilization_factor
(sys,
result,
a_processor,
output);
if output = xml_output then
result := result & end_feasibility_Test & unbounded_lf;
result :=
result &
start_feasibility_Test &
To_Unbounded_String (" name=""") &
Lb_Xml_Worst_Case_Response_Time (Current_Language) &
To_Unbounded_String (""" reference=""") &
a_processor.name &
To_Unbounded_String (""">") &
unbounded_lf;
end if;
compute_feasibility_response_time
(sys,
result,
periodic,
no_memory_interference,
no_crpd,
a_processor,
output);
if output = xml_output then
result := result & end_feasibility_Test;
end if;
end compute_feasibility_basics;
------------------------------------------------------------------------
-- Compute_Feasibility_By_Demand_Bound_Function
-- "Preemptively Scheduling Hard-Real-Time Sporadic Tasks on One processor",
-- Baruah, Mok and Rosier, 1990
-- Implementation Notes:
-- S. Rubini, 11/2018
------------------------------------------------------------------------
procedure compute_feasibility_by_demand_bound_function
(sys : in system;
result : in out Unbounded_String;
a_processor : in generic_processor_ptr;
output : in output_format := string_output)
is
compute_report : feasibility_test.processor_demand
.feasibility_test_report;
a_scheduler : generic_scheduler_ptr;
begin
put_debug ("Call Compute_Feasibility_By_Demand_Bound_Function");
result :=
result &
lb_feasibility_dbf (Current_Language) &
unbounded_lf &
unbounded_lf;
a_scheduler := build_a_scheduler (a_processor);
begin
sporadic_periodic_task_set_feasibility_test
(a_scheduler,
sys.tasks,
a_processor.name,
compute_report);
-- report results
if compute_report.feasible then
if compute_report.motivation = by_processor_utilization_factor then
result :=
result &
lb_sched_explanation1 (Current_Language) &
lb_sched_explanation12 (Current_Language) &
format (compute_report.processor_utilization_bound) &
To_Unbounded_String (" (") &
lb_see (Current_Language) &
To_Unbounded_String ("[1], page 6). ") &
unbounded_lf &
lb_minus &
lb_utilization_with_period (Current_Language) &
format (compute_report.processor_utilization) &
unbounded_lf &
unbounded_lf;
elsif compute_report.motivation = by_dbf then
result :=
result &
lb_minus &
lb_sched_explanation_dbf1 (Current_Language) &
compute_report.check_interval'img &
To_Unbounded_String (" (") &
lb_see (Current_Language) &
To_Unbounded_String ("[22], page 6). ") &
unbounded_lf;
else
null; -- TODO raise an exception
end if;
else -- unfeasible
if compute_report.motivation = by_processor_utilization_factor then
result :=
result &
lb_sched_explanation2 (Current_Language) &
lb_sched_explanation22 (Current_Language) &
format (compute_report.processor_utilization_bound) &
To_Unbounded_String (" (") &
lb_see (Current_Language) &
To_Unbounded_String ("[1], page 6). ") &
unbounded_lf &
lb_minus &
lb_utilization_with_period (Current_Language) &
format (compute_report.processor_utilization) &
unbounded_lf;
elsif compute_report.motivation = by_dbf then
-- Compute_Report.Overrun_Time /= 0
result :=
result &
lb_minus &
lb_sched_explanation_dbf2 (Current_Language) &
compute_report.check_interval'img &
To_Unbounded_String (" (") &
lb_see (Current_Language) &
To_Unbounded_String ("[22], page ?). ") &
unbounded_lf &
lb_minus &
lb_feasibility_dbf_check_interval (Current_Language) &
compute_report.check_interval'img &
unbounded_lf &
lb_minus &
lb_feasibility_dbf_overrun_instant (Current_Language) &
compute_report.overrun_time'img &
unbounded_lf;
else
null;
end if;
end if;
exception
when task_set.task_must_be_sporadic_or_periodic =>
result :=
result &
lb_minus &
lb_compute_scheduling_error_27 (Current_Language) &
unbounded_lf;
when invalid_scheduler =>
result :=
result &
lb_minus &
lb_compute_scheduling_error_18 (Current_Language) &
unbounded_lf;
end;
end compute_feasibility_by_demand_bound_function;
end call_scheduling_framework;