------------------------------------------------------------------------------ ------------------------------------------------------------------------------ -- 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-2020, Frank Singhoff, Alain Plantec, Jerome Legrand, -- Hai Nam Tran, Stephane Rubini -- -- The Cheddar project was started in 2002 by -- Frank Singhoff, Lab-STICC UMR 6285, 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$ -- $Date$ -- $Author: singhoff $ ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ with Ada.Text_IO; with Text_IO; use Text_IO; with Gtk.Menu_Item; use Gtk.Menu_Item; with Gtk; use Gtk; with Gtk.Main; use Gtk.Main; with Glib.Error; use Glib.Error; with Gtk.Widget; use Gtk.Widget; with Gtk.Window; use Gtk.Window; with Gtk.Dialog; use Gtk.Dialog; with Gtk.Drawing_Area; use Gtk.Drawing_Area; with Gtk.About_Dialog; use Gtk.About_Dialog; with Gtk.Label; use Gtk.Label; with Gtk.Text_Buffer; use Gtk.Text_Buffer; with Gtk.Combo_Box; use Gtk.Combo_Box; with Glib; use Glib; with Glib.Object; use Glib.Object; with graphical_editor; use graphical_editor; with graphical_editor.scheduling_simulation_draw_callbacks; use graphical_editor.scheduling_simulation_draw_callbacks; with graphical_editor.processors; use graphical_editor.processors; with framework_config; use framework_config; with translate; use translate; with tasks; use tasks; with task_set; use task_set; use task_set.generic_task_set; with processors; use processors; with processor_set; use processor_set; use processor_set.generic_processor_set; with graphical_editor.user_message; use graphical_editor.user_message; with Gtk.Check_Button; use Gtk.Check_Button; with editor_config; use editor_config; with graphical_editor.generic_package_widget; use graphical_editor.generic_package_widget; with graphical_editor.event_analyzers; use graphical_editor.event_analyzers; with graphical_editor.scheduling_simulation_draw_callbacks; use graphical_editor.scheduling_simulation_draw_callbacks; with feasibility_test.feasibility_interval; use feasibility_test.feasibility_interval; with double_util; use double_util; with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; with Ada.Numerics.Aux; use Ada.Numerics.Aux; with framework; use framework; with multiprocessor_services_interface; use multiprocessor_services_interface; use multiprocessor_services_interface.scheduling_result_per_processor_package; package body graphical_editor.scheduling_simulation_callbacks is procedure read_scheduling_customization_widget (object : access gtkada_builder_record'class) is begin graphical_editor.scheduling_simulation_callbacks.close_widget (object); customized_simulation := True; last_selected_processor := To_Unbounded_String (Get_Active_Text (gtk_combo_box (Get_Object (object, "combobox1")))); schedule_and_export_event_table := Get_Active (gtk_check_button (Get_Object (object, "checkbutton12"))); schedule_all_processors := Get_Active (gtk_check_button (Get_Object (object, "checkbutton9"))); run_event_analyzer_from_simulation := Get_Active (gtk_check_button (Get_Object (object, "checkbutton10"))); preemption_from_simulation := Get_Active (gtk_check_button (Get_Object (object, "checkbutton14"))); context_switch_from_simulation := Get_Active (gtk_check_button (Get_Object (object, "checkbutton13"))); schedule_and_display_event_table := Get_Active (gtk_check_button (Get_Object (object, "checkbutton11"))); schedule_and_export_event_table := Get_Active (gtk_check_button (Get_Object (object, "checkbutton12"))); event_table_file_name := get_value_buffer_string (gtk_text_buffer (Get_Object (object, "textbuffer1"))); xml_event_table_file_name := get_value_buffer_string (gtk_text_buffer (Get_Object (object, "textbuffer1"))); response_time_from_simulation (worst_case) := Get_Active (gtk_check_button (Get_Object (object, "checkbutton1"))); response_time_from_simulation (best_case) := Get_Active (gtk_check_button (Get_Object (object, "checkbutton3"))); response_time_from_simulation (average_case) := Get_Active (gtk_check_button (Get_Object (object, "checkbutton5"))); response_time_from_simulation (plot_case) := Get_Active (gtk_check_button (Get_Object (object, "checkbutton7"))); blocking_time_from_simulation (worst_case) := Get_Active (gtk_check_button (Get_Object (object, "checkbutton2"))); blocking_time_from_simulation (best_case) := Get_Active (gtk_check_button (Get_Object (object, "checkbutton4"))); blocking_time_from_simulation (average_case) := Get_Active (gtk_check_button (Get_Object (object, "checkbutton6"))); blocking_time_from_simulation (plot_case) := Get_Active (gtk_check_button (Get_Object (object, "checkbutton8"))); -- Do controls : if everything is ok, open next windows -- Otherwise continue the current windows -- if schedule_and_export_event_table then if xml_event_table_file_name = empty_string then show_message_box (lb_event_table_file_name (current_language) & lb_mandatory (current_language)); return; end if; end if; -- Display the widget to select scheduling simulation duration -- graphical_editor.scheduling_simulation_callbacks .show_scheduling_simulation_duration_widget (object); end read_scheduling_customization_widget; procedure show_scheduling_simulation_duration_widget (object : access gtkada_builder_record'class) is builder : gtkada_builder; error : Glib.Error.gerror; buf1 : gobject; buf2 : gobject; buf3 : gobject; a_task : generic_task_ptr; iterator1 : tasks_iterator; a_processor : generic_processor_ptr; iterator2 : processors_iterator; max_period : Natural := 0; period : Natural := 0; max_draw : Natural := 1500; validate : Boolean; double_period : Double; msg : Unbounded_String; begin if (get_number_of_elements (sys.tasks) = 0) then show_message_box (lb_define_tasks_before (current_language)); return; end if; Gtk.Main.Init; Gtk_New (builder); error := Add_From_File (builder, To_String (glade_path) & "scheduling_simulation_draw.glade"); if error /= null then Ada.Text_IO.Put_Line ("Error : " & Get_Message (error)); Error_Free (error); return; end if; buf1 := Get_Object (builder, "textbuffer1"); buf2 := Get_Object (builder, "textbuffer2"); buf3 := Get_Object (builder, "textbuffer3"); reset_iterator (sys.tasks, iterator1); if not is_empty (sys.tasks) then loop current_element (sys.tasks, a_task, iterator1); if (a_task.task_type = periodic_type) or (a_task.task_type = poisson_type) or (a_task.task_type = sporadic_type) then max_period := Natural'max (max_period, periodic_task_ptr (a_task).period); else max_period := Natural'max (max_period, a_task.deadline); end if; exit when is_last_element (sys.tasks, iterator1); next_element (sys.tasks, iterator1); end loop; end if; reset_iterator (sys.processors, iterator2); loop current_element (sys.processors, a_processor, iterator2); if (get_number_of_task_from_processor (sys.tasks, a_processor.name) /= 0) then begin calculate_feasibility_interval (sys, a_processor, validate, double_period, msg); period := Natural (double_period); if period > max_period then max_period := period; end if; exception when others => null; end; end if; exit when is_last_element (sys.processors, iterator2); next_element (sys.processors, iterator2); end loop; if (max_period < max_draw) then max_draw := max_period; end if; Set_Text (gtk_text_buffer (buf1), max_period'img); Set_Text (gtk_text_buffer (buf2), "0"); Set_Text (gtk_text_buffer (buf3), max_draw'img); Register_Handler (Builder => builder, Handler_Name => "on_button1_clicked", Handler => graphical_editor.scheduling_simulation_draw_callbacks .read_scheduling_duration_and_draw_scheduling' access); Register_Handler (Builder => builder, Handler_Name => "on_button2_clicked", Handler => graphical_editor.scheduling_simulation_draw_callbacks.close_widget' access); Do_Connect (builder); Gtk.Widget.Show_All (Get_Widget (builder, "window1")); Gtk.Main.Main; Unref (builder); end show_scheduling_simulation_duration_widget; procedure show_scheduling_simulation_zoom_in (object : access gtkada_builder_record'class) is begin if zoom_level < 5 then zoom_level := zoom_level + 1; Set_Text (zoom_level_entry, To_String (display_zoom)); end if; if (sched.nb_entries /= 0) then draw_time_line; cb.Connect (gtk_drawing_area (drawing_area_cheddar), "expose_event", cb.To_Marshaller (expose'access)); end if; end show_scheduling_simulation_zoom_in; procedure show_scheduling_simulation_zoom_out (object : access gtkada_builder_record'class) is begin if zoom_level > -5 then zoom_level := zoom_level - 1; Set_Text (zoom_level_entry, To_String (display_zoom)); end if; if (sched.nb_entries /= 0) then draw_time_line; cb.Connect (gtk_drawing_area (drawing_area_cheddar), "expose_event", cb.To_Marshaller (expose'access)); end if; end show_scheduling_simulation_zoom_out; procedure show_scheduling_simulation_zoom_reset (object : access gtkada_builder_record'class) is begin zoom_level := 0; Set_Text (zoom_level_entry, To_String (display_zoom)); if (sched.nb_entries /= 0) then draw_time_line; cb.Connect (gtk_drawing_area (drawing_area_cheddar), "expose_event", cb.To_Marshaller (expose'access)); end if; end show_scheduling_simulation_zoom_reset; procedure show_scheduling_simulation_zoom_fit (object : access gtkada_builder_record'class) is width : gint; height : gint; target_zoom : Double; begin Get_Size (window_cheddar, width, height); if (sched.nb_entries /= 0) then target_zoom := (Double (width) / Double (scheduling_base_period)); zoom_level := zoom_range'first; for i in zoom_range'range loop if zoom_values (i) * Double (timeunit_margin) / 100.0 < target_zoom then zoom_level := i; end if; end loop; Set_Text (zoom_level_entry, To_String (display_zoom)); draw_time_line; cb.Connect (gtk_drawing_area (drawing_area_cheddar), "expose_event", cb.To_Marshaller (expose'access)); end if; end show_scheduling_simulation_zoom_fit; procedure close_widget (object : access gtkada_builder_record'class) is my_widget : gobject; begin my_widget := Get_Object (object, "window1"); Destroy_Cb (gtk_widget (my_widget)); Gtk.Main.Main_Quit; end close_widget; end graphical_editor.scheduling_simulation_callbacks;