with systems; use systems; with tasks; use tasks; with task_set; use task_set; use task_set.generic_task_set; with dependencies; use dependencies; with parameters; use parameters; with parameters.extended; use parameters.extended; use parameters.framework_parameters_table_package; with framework; use framework; with call_framework; use call_framework; with call_framework_interface; use call_framework_interface; use call_framework_interface.framework_response_package; use call_framework_interface.framework_request_package; with call_scheduling_framework; use call_scheduling_framework; with multiprocessor_services; use multiprocessor_services; with multiprocessor_services_interface; use multiprocessor_services_interface; use multiprocessor_services_interface.scheduling_result_per_processor_package; with core_units; use core_units; with scheduler_interface; use scheduler_interface; with processor_interface; use processor_interface; with processors; use processors; with processor_set; use processor_set; with task_dependencies; use task_dependencies; with scheduler_interface; use scheduler_interface; with GNAT.Command_Line; with GNAT.OS_Lib; use GNAT.OS_Lib; with debug; use debug; with io_tools; use io_tools; with Text_IO; use Text_IO; with version; use version; with Ada.Exceptions; use Ada.Exceptions; with Ada.Numerics.Aux; use Ada.Numerics.Aux; with Ada.Containers.Ordered_Maps; package body voltage_scaling is -- Init voltage scaling procedure dvfs_init_voltage_scaling(a_processor : in generic_processor_ptr) is processor_type : processors_type; a_core : core_unit_ptr; begin processor_type := a_processor.processor_type; if (processor_type = monocore_type) then a_core := mono_core_processor_ptr (a_processor).core; else a_core := multi_cores_processor_ptr (a_processor).cores.entries (0); end if; scheduler_type := a_core.scheduling.scheduler_type; -- reset global variable curr_freq := 100; curr_time_task_exec := 0; if DVS_map_package.Is_Empty(DVS_map) = false then DVS_map_package.Clear(DVS_map); end if; end dvfs_init_voltage_scaling; -- Select Frequency function select_frequency_static_voltage_scaling ( my_tasks : DVS_map_subtype ) return Double is resEDF :boolean; resRM :boolean; res :Double; pi :natural; my_Cursor : DVS_map_package.Cursor; begin --init pi := 0; resEDF := false; res := -1.0; --Début algo select my_Cursor := DVS_map_package.First(my_tasks); while DVS_map_package.Has_Element(my_Cursor) loop if pi < periodic_task_ptr(DVS_map_package.Element(my_Cursor).a_task).period then pi := periodic_task_ptr(DVS_map_package.Element(my_Cursor).a_task).period; end if; DVS_map_package.Next(my_Cursor); end loop; if scheduler_type = earliest_deadline_first_protocol then Put_LINE("Static Voltage Scaling"); Put_LINE("EDF Scheduler"); for i in freqs'First..freqs'Last loop resEDF := EDF_test_static_voltage_scaling(my_tasks,freqs(i)/ freqs(freqs'Last)); res := freqs(i); if resEDF then if show_detail then Put("OK with speed "); Put(Double 'image(freqs(i))); Put_LINE(" with edf"); end if; res := freqs(i); else if show_detail then Put("NOK with speed "); Put(Double 'image(freqs(i))); Put_LINE(" with edf"); end if; end if; exit when resEDF; end loop; else if scheduler_type = rate_monotonic_protocol then Put_LINE("Static Voltage Scaling"); Put_LINE("RM Scheduler"); for i in freqs'First..freqs'Last loop resRM := RM_test_static_voltage_scaling(my_tasks, freqs(i)/freqs(freqs'Last) ,pi); res := freqs(i); if resRM then if show_detail then Put("OK with speed "); Put(Double 'image(freqs(i))); Put_LINE(" with rm"); end if; res := freqs(i); else if show_detail then Put("NOK with speed "); Put(Double 'image(freqs(i))); Put_LINE(" with rm"); end if; end if; exit when resRM; end loop; else Put_LINE("/!\ Not RM or EDF scheduler /!\"); end if; end if; return res; end select_frequency_static_voltage_scaling; -- EDF function EDF_test_static_voltage_scaling ( my_tasks : DVS_map_subtype; freq : Double ) return boolean is a_task : Generic_Task_Ptr; my_Cursor : DVS_map_package.Cursor; somme : Double; tmp : Double; tmp2 : Double; begin somme := 0.0; my_Cursor := DVS_map_package.First(my_tasks); while DVS_map_package.Has_Element(my_Cursor) loop a_task := DVS_map_package.Element(my_Cursor).a_task; tmp := Double (a_task.capacity)/100.0; tmp2 := Double (periodic_task_ptr (a_task).period); somme := somme + (tmp/tmp2); DVS_map_package.Next(my_Cursor); end loop; if somme <= freq then return True; else return False; end if; end EDF_test_static_voltage_scaling; -- RM function RM_test_static_voltage_scaling ( my_tasks : DVS_map_subtype; freq : Double; pi : natural ) return boolean is a_task : Generic_Task_Ptr; my_Cursor : DVS_map_package.Cursor; somme : Double; tmp : Double; tmp2 : Double; tmp3 : Double; type tab_period_type is array (0.. natural( DVS_map_package.Length(my_tasks))-1) of DVS_hashmap_type_element; tab_period : tab_period_type; tmp_period : DVS_hashmap_type_element; i : natural; begin i:=0; my_Cursor := DVS_map_package.First(my_tasks); while DVS_map_package.Has_Element(my_Cursor) loop tab_period (i) := DVS_map_package.Element(my_Cursor); i := i + 1; DVS_map_package.Next(my_Cursor); end loop; -- table order P1 <= P2 <= .... <= Pi if natural (DVS_map_package.Length(my_tasks)) >=2 then i :=0; while i <= tab_period'Length-2 loop if (periodic_task_ptr( tab_period(i).a_task).period) > (periodic_task_ptr( tab_period(i+1).a_task).period) then tmp_period := tab_period(i); tab_period(i) := tab_period(i+1); tab_period(i+1) := tmp_period; i :=0; else i := i+1; end if; end loop; end if; tmp3 := Double (pi); for i in 0 .. Tab_Period'Length-1 loop somme := 0.0; for j in 0 .. i loop a_task := Tab_Period(j).a_task; tmp := Double (a_task.capacity)/100.0; tmp2 := Double (periodic_task_ptr (a_task).period); somme := somme + (tmp* (Double'Ceiling(tmp3/tmp2))); end loop; if somme > (freq * tmp3) then return False; end if; end loop; return True; end RM_test_static_voltage_scaling; -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --Cycle Conserving --EDF function select_frequency_cycle_conserving_edf (a_task_Ui : DVS_map_subtype) return Double is tmp :boolean; res :Double; my_Cursor : DVS_map_package.Cursor; begin res := 0.0; tmp := false; my_Cursor := DVS_map_package.First(a_task_Ui); while DVS_map_package.Has_Element(my_Cursor) loop res := res + DVS_map_package.Element(my_Cursor).element; DVS_map_package.Next(my_Cursor); end loop; for i in freqs'First..freqs'Last loop if res <= ( freqs(i) /freqs(freqs'Last) ) then tmp := true; if show_detail then Put("OK avec une frequence "); Put(Double 'image(freqs(i))); Put_LINE(" en edf"); end if; res := freqs(i); else if show_detail then Put("NOK avec une frequence "); Put(Double 'image(freqs(i))); Put_LINE(" en edf"); end if; end if; exit when tmp; end loop; return res; end select_frequency_cycle_conserving_edf; procedure cycle_conserving_task_release_edf(a_task : Generic_Task_Ptr; new_frequency : out Double) is tmp : Double; tmp1 : Double; tmp2 : Double; DVS_EDF_element:DVS_hashmap_type_element; begin tmp1 := Double (a_task.capacity)/100.0; tmp2 := Double (periodic_task_ptr (a_task).period); DVS_EDF_element := ( c_left => 0.0, element => tmp1/tmp2, a_task => a_task, release_time => DVS_map_package.Element(DVS_map,a_task.name).release_time ); DVS_map_package.Replace(DVS_map,a_task.name,DVS_EDF_element); tmp := select_frequency_cycle_conserving_edf(DVS_map); if show_detail then Put("Frequence :"); Put(Double 'image(tmp)); Put_LINE(" en edf"); end if; new_frequency := tmp; end cycle_conserving_task_release_edf; procedure cycle_conserving_task_completion_edf (a_task : Generic_Task_Ptr; new_frequency : out Double) is tmp : Double; tmp1 : Double; tmp2 : Double; DVS_EDF_element:DVS_hashmap_type_element; begin tmp1 := (DVS_map_package.Element(DVS_map,a_task.name).c_left); tmp2 := Double (periodic_task_ptr (a_task).period); DVS_EDF_element := ( c_left => (DVS_map_package.Element(DVS_map,a_task.name).c_left), element => tmp1/tmp2, a_task => a_task, release_time => (DVS_map_package.Element(DVS_map,a_task.name).release_time) ); DVS_map_package.Replace(DVS_map,a_task.name,DVS_EDF_element); tmp := select_frequency_cycle_conserving_edf(DVS_map); if show_detail then Put("Frequence :"); Put(Double 'image(tmp)); Put_LINE(" en edf"); end if; new_frequency := tmp; end cycle_conserving_task_completion_edf; --RM function select_frequency_cycle_conserving_rm ( a_task_Ui : DVS_map_subtype; current_time : natural; task_is_release : boolean ) return Double is tmp :boolean; element :Double; res :Double; sm :Natural; my_Cursor : DVS_map_package.Cursor; DVS_RM_element:DVS_hashmap_type_element; begin element := 0.0; tmp := false; sm := max_cycles_until_next_deadline(DVS_map,current_time); if task_is_release = false then sm := sm -1; end if; my_Cursor := DVS_map_package.First(a_task_Ui); while DVS_map_package.Has_Element(my_Cursor) loop DVS_RM_element := DVS_map_package.Element(my_Cursor); element := element + DVS_RM_element.element; DVS_map_package.Next(my_Cursor); end loop; res := element / Double(sm); Put("Frequence calcule :"); Put_LINE(Double 'image(res)); for i in freqs'First..freqs'Last loop if res <= ( freqs(i) /freqs(freqs'Last) ) then tmp := true; if show_detail then Put("Peut etre OK avec une frequence "); Put(Double 'image(freqs(i))); Put_LINE(" en rm"); end if; res := freqs(i); else if show_detail then Put("NOK avec une frequence "); Put(Double 'image(freqs(i))); Put_LINE(" en rm"); end if; end if; exit when tmp; end loop; return res; end select_frequency_cycle_conserving_rm; function max_cycles_until_next_deadline(a_task_Ui : in DVS_map_subtype ; current_time : in natural) return natural is my_Cursor : DVS_map_package.Cursor; res : natural; tmp1 : natural; tmp2 : natural; begin my_Cursor := DVS_map_package.First(a_task_Ui); res := DVS_map_package.Element(my_Cursor).a_task.deadline; while DVS_map_package.Has_Element(my_Cursor) loop tmp1 := (current_time/ DVS_map_package.Element(my_Cursor).a_task.deadline) + 1 ; tmp2 := (tmp1 * DVS_map_package.Element(my_Cursor).a_task.deadline - current_time); if (res > tmp2) then res := tmp2; end if; DVS_map_package.Next(my_Cursor); end loop; if show_detail then Put("Max cycle until next deadline"); Put_LINE(natural 'image(res)); end if; return res ; end max_cycles_until_next_deadline; procedure cycle_conserving_task_release_rm( a_task : Generic_Task_Ptr; current_time : natural; new_frequency : out Double) is DVS_RM_element:DVS_hashmap_type_element; sm : natural; sj : Double; begin DVS_RM_element := ( c_left => Double (a_task.capacity)/100.0, element => 0.0, a_task => a_task, release_time => DVS_map_package.Element(DVS_map,a_task.name).release_time ); DVS_map_package.Replace(DVS_map,a_task.name,DVS_RM_element); sm := max_cycles_until_next_deadline(DVS_map,current_time); sj := Double (sm) * (fj / (freqs(freqs'Last))); cycle_conserving_task_allocate_cycles(sj); new_frequency := select_frequency_cycle_conserving_rm(DVS_map,current_time,true); if show_detail then Put("Frequence obtenue :"); Put(Double 'image(new_frequency)); Put_LINE(" en rm"); end if; end cycle_conserving_task_release_rm; procedure cycle_conserving_task_completion_rm ( a_task : Generic_Task_Ptr; current_time : natural; new_frequency : out Double) is DVS_RM_element:DVS_hashmap_type_element; begin DVS_RM_element := ( c_left => 0.0, element => 0.0, a_task => a_task, release_time => DVS_map_package.Element(DVS_map,a_task.name).release_time ); DVS_map_package.Replace(DVS_map,a_task.name,DVS_RM_element); new_frequency := select_frequency_cycle_conserving_rm(DVS_map, current_time,false); if show_detail then Put("Frequence obtenue :"); Put(Double 'image(new_frequency)); Put_LINE(" en rm"); end if; end cycle_conserving_task_completion_rm; procedure cycle_conserving_task_execution_rm (a_task : Generic_Task_Ptr) is DVS_RM_element : DVS_hashmap_type_element; tmp_c_left : Double; tmp_d : Double; begin tmp_c_left := DVS_map_package.Element(DVS_map,a_task.name).c_left - (1.0* double(curr_freq)/100.0); if tmp_c_left < 0.0 then tmp_c_left := 0.0; end if; tmp_d := DVS_map_package.Element(DVS_map,a_task.name).element - (1.0* double (curr_freq)/100.0); if tmp_d < 0.0 then tmp_d := 0.0; end if; DVS_RM_element := ( c_left => tmp_c_left, element => tmp_d, a_task => a_task, release_time => DVS_map_package.Element(DVS_map,a_task.name).release_time ); DVS_map_package.Replace(DVS_map,a_task.name,DVS_RM_element); end cycle_conserving_task_execution_rm; procedure cycle_conserving_task_allocate_cycles(ki : Double) is my_Cursor : DVS_map_package.Cursor; DVS_RM_element:DVS_hashmap_type_element; k : Double; type Type_Tab_Period is array (0.. natural( DVS_map_package.Length(DVS_map))-1) of DVS_hashmap_type_element; Tab_Period : Type_Tab_Period; tmp_period : DVS_hashmap_type_element; i : natural; begin k := ki; i := 0; my_Cursor := DVS_map_package.First(DVS_map); while DVS_map_package.Has_Element(my_Cursor) loop Tab_Period(i) := DVS_map_package.Element(my_Cursor); i := i + 1; DVS_map_package.Next(my_Cursor); end loop; if natural (DVS_map_package.Length(DVS_map)) >=2 then i :=0; while i <= Tab_Period'Length-2 loop if periodic_task_ptr(Tab_Period(i).a_task).period > periodic_task_ptr(Tab_Period(i+1).a_task).period then tmp_period := Tab_Period(i); Tab_Period(i) := Tab_Period(i+1); Tab_Period(i+1) := tmp_period; i :=0; else i := i+1; end if; end loop; end if; my_Cursor := DVS_map_package.First(DVS_map); for I in 0 .. Tab_Period'Length-1 loop if Tab_Period(i).c_left < k then DVS_RM_element := ( c_left => Tab_Period(i).c_left, element => Tab_Period(i).c_left, a_task => Tab_Period(i).a_task, release_time => Tab_Period(i).release_time ); k:= k - Tab_Period(i).c_left; else DVS_RM_element := ( c_left => Tab_Period(i).c_left, element => k, a_task => Tab_Period(i).a_task, release_time =>Tab_Period(i).release_time ); k := 0.0; end if; Tab_Period(i) := DVS_RM_element; if show_detail then Put_Line("c_left: "& Double 'image( Tab_Period(i).c_left)); Put_Line("di: "& Double 'image(Tab_Period(i).element)); Put_Line("k: "& Double 'image(k)); end if; DVS_map_package.Replace(DVS_map,Tab_Period(i).a_task.name,DVS_RM_element); end loop; end cycle_conserving_task_allocate_cycles; -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --Look-Ahead DVFS function select_frequency_look_ahead (x : Double) return Double is res : Double; tmp : boolean; begin res := 0.0; tmp := false; for i in freqs'First..freqs'Last loop if x <= ( freqs(i) /freqs(freqs'Last) ) then tmp := true; if show_detail then Put("OK avec une frequence "); Put(Double 'image(freqs(i))); Put_LINE(" en edf"); end if; res := freqs(i) /freqs(freqs'Last); else if show_detail then Put("NOK avec une frequence "); Put(Double 'image(freqs(i))); Put_LINE(" en edf"); end if; end if; exit when tmp; end loop; return res; end select_frequency_look_ahead; procedure look_ahead_task_release (a_task : Generic_Task_Ptr; current_time : in natural; new_frequency : out Double) is DVS_Look_Ahead_EDF_element : DVS_hashmap_type_element; begin if current_time /= 0 then DVS_Look_Ahead_EDF_element := ( c_left => Double (a_task.capacity)/100.0, a_task => a_task, element => (DVS_map_package.Element(DVS_map,a_task.name).element) + Double((periodic_task_ptr( DVS_map_package.Element(DVS_map,a_task.name).a_task).period)), release_time => DVS_map_package.Element(DVS_map,a_task.name).release_time ); DVS_map_package.Replace(DVS_map,a_task.name,DVS_Look_Ahead_EDF_element); end if; look_ahead_task_defer(DVS_map,current_time,new_frequency); end look_ahead_task_release; procedure look_ahead_task_completion (a_task : Generic_Task_Ptr; current_time : in natural; new_frequency : out Double) is DVS_Look_Ahead_EDF_element : DVS_hashmap_type_element; begin DVS_Look_Ahead_EDF_element := ( c_left => 0.0, a_task => a_task, element => DVS_map_package.Element(DVS_map,a_task.name).element, release_time => DVS_map_package.Element(DVS_map,a_task.name).release_time ); DVS_map_package.Replace(DVS_map,a_task.name,DVS_Look_Ahead_EDF_element); look_ahead_task_defer(DVS_map,current_time,new_frequency); end look_ahead_task_completion; procedure look_ahead_task_execution (a_task : Generic_Task_Ptr) is DVS_Look_Ahead_EDF_element : DVS_hashmap_type_element; tmp_c_left : double; begin if DVS_map_package.Element(DVS_map,a_task.name).c_left = 0.0 then DVS_Look_Ahead_EDF_element := ( c_left => 0.0, a_task => a_task, element => Double ((DVS_map_package.Element(DVS_map,a_task.name).element)), release_time => DVS_map_package.Element(DVS_map,a_task.name).release_time ); else tmp_c_left := (DVS_map_package.Element(DVS_map,a_task.name).c_left) - (1.0* double(curr_freq)/100.0); if tmp_c_left < 0.0 then tmp_c_left := 0.0; end if; DVS_Look_Ahead_EDF_element := ( c_left => tmp_c_left, a_task => a_task, element => Double ((DVS_map_package.Element(DVS_map,a_task.name).element)), release_time => DVS_map_package.Element(DVS_map,a_task.name).release_time ); end if; DVS_map_package.Replace(DVS_map,a_task.name,DVS_Look_Ahead_EDF_element); end look_ahead_task_execution; procedure look_ahead_task_defer (a_task_Ui : DVS_map_subtype; current_time : in natural; new_frequency : out double) is u : Double; res : Double; s : Double; x : Double; my_Cursor : DVS_map_package.Cursor; tmp1 : Double; tmp2 : Double; type testTabDeadline is array (0.. natural( DVS_map_package.Length(a_task_Ui))-1) of DVS_hashmap_type_element; TabDeadline : testTabDeadline; tmpdealine : DVS_hashmap_type_element; i : natural; begin res := 0.0; u := 0.0; i := 0; my_Cursor := DVS_map_package.First(a_task_Ui); while DVS_map_package.Has_Element(my_Cursor) loop tmp1 := Double (DVS_map_package.Element(my_Cursor).a_task.capacity)/100.0; tmp2 := Double (periodic_task_ptr( DVS_map_package.Element(my_Cursor).a_task).period); u := u + (tmp1 / tmp2); TabDeadline (i) := DVS_map_package.Element(my_Cursor); i := i + 1; DVS_map_package.Next(my_Cursor); end loop; s := 0.0; if natural (DVS_map_package.Length(a_task_Ui)) >=2 then i :=0; while i <= TabDeadline'Length-2 loop if TabDeadline(i).element < TabDeadline(i+1).element then tmpdealine := TabDeadline(i); TabDeadline(i) := TabDeadline(i+1); TabDeadline(i+1) := tmpdealine; i :=0; else i := i+1; end if; end loop; end if; for I in 0 .. TabDeadline'Length-1 loop u := u - (Double (TabDeadline(I).a_task.capacity)/100.0) / Double ((periodic_task_ptr( TabDeadline(I).a_task).period)); x := Double'Max(0.0, TabDeadline(I).c_left - (1.0- u)* Double((TabDeadline(I).element - TabDeadline(TabDeadline'Length-1).element))); if TabDeadline(I).element /= TabDeadline(TabDeadline'Length-1).element then u := u + (TabDeadline(I).c_left - x) / Double((TabDeadline(I).element - TabDeadline(TabDeadline'Length-1).element)); end if; s := s + x; if show_detail then Put_Line("c_left: "& Double 'image( TabDeadline(I).c_left)); Put_Line("x: "& Double 'image(x)); Put_Line("u: "& Double 'image(u)); Put_Line("s: "& Double 'image(s)); end if; end loop; if (TabDeadline(TabDeadline'Length-1).element - Double(current_time)) = 0.0 then s := 1.0; else s := s/(TabDeadline(TabDeadline'Length-1).element - Double(current_time)); end if; if show_detail then Put("Frequence calcule :"); Put_Line(Double 'image(s)); end if; res := select_frequency_look_ahead(s); if show_detail then Put("Frequence obtenue :"); Put(Double 'image(res)); Put_LINE(" en EDF"); end if; new_frequency := res; end look_ahead_task_defer; -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- procedure new_frequency_double_to_integer(new_frequency_double : in Double; new_frequency : out integer) is begin if new_frequency_double = 1.0 then new_frequency := 100; else if new_frequency_double = 0.75 then new_frequency := 75; else if new_frequency_double = 0.50 then new_frequency := 50; else if new_frequency_double = 0.25 then new_frequency := 25; else new_frequency := curr_freq; end if; end if; end if; end if; if show_detail then Put_LINE("DVFS : new_frequency_double_to_integer new frequency= " & integer'image(new_frequency)); end if; curr_freq :=new_frequency; end new_frequency_double_to_integer; procedure dvfs_upon_running_task (an_event : in time_unit_event_ptr; current_time : in natural; new_frequency : out integer) is my_Cursor : DVS_map_package.Cursor; new_frequency_double : Double :=0.0; DVS_element :DVS_hashmap_type_element; begin if only_static_algorithm = False then Put_LINE("DVFS : running_task"); put_line("task name = " & to_string(an_event.running_task.name)); Put_LINE("Current_Time: " & Natural 'image(current_time)); -- Check if the current time correspond to a task release curr_time_task_exec := current_time; if scheduler_type = earliest_deadline_first_protocol then my_Cursor := DVS_map_package.First(DVS_map); while DVS_map_package.Has_Element(my_Cursor) loop if DVS_map_package.Element(my_Cursor).release_time = current_time then if look_ahead_algorithm = True then look_ahead_task_release(DVS_map_package.Element(my_Cursor).a_task,current_time, new_frequency_double ); else cycle_conserving_task_release_edf(DVS_map_package.Element(my_Cursor).a_task,new_frequency_double); end if; new_frequency_double_to_integer(new_frequency_double,new_frequency); end if; DVS_map_package.Next(my_Cursor); end loop; if look_ahead_algorithm = True then look_ahead_task_execution(an_event.running_task); else DVS_element := ( c_left => (DVS_map_package.Element(DVS_map,an_event.running_task.name).c_left) + (1.0* double (curr_freq)/100.0), a_task => an_event.running_task, element => (DVS_map_package.Element(DVS_map,an_event.running_task.name).element), release_time => (DVS_map_package.Element(DVS_map,an_event.running_task.name).release_time) ); DVS_map_package.Replace(DVS_map,an_event.running_task.name,DVS_element); end if; else if scheduler_type = rate_monotonic_protocol then my_Cursor := DVS_map_package.First(DVS_map); while DVS_map_package.Has_Element(my_Cursor) loop if DVS_map_package.Element(my_Cursor).release_time = current_time then cycle_conserving_task_release_rm(DVS_map_package.Element(my_Cursor).a_task,current_time, new_frequency_double ); new_frequency_double_to_integer(new_frequency_double,new_frequency); end if; DVS_map_package.Next(my_Cursor); end loop; cycle_conserving_task_execution_rm(an_event.running_task); end if; end if; end if; new_frequency_double_to_integer(new_frequency_double,new_frequency); Put_LINE("Speed: " & Integer 'image(new_frequency)); end dvfs_upon_running_task; procedure dvfs_upon_task_release (an_event : in time_unit_event_ptr ; current_time : in natural;new_frequency : out integer ) is new_frequency_double : Double:=0.0; DVS_element :DVS_hashmap_type_element; begin Put_LINE("DVFS : task release"); put_line("task name = " & to_string(an_event.activation_task.name)); --put_line("Release time = "& Natural 'image(current_time)); if only_static_algorithm = True then if current_time = 0 then if DVS_map_package.Contains(DVS_map, an_event.activation_task.name) then DVS_element := ( c_left => 0.0, a_task => an_event.activation_task, element => 0.0, release_time => current_time ); DVS_map_package.Replace(DVS_map,an_event.activation_task.name,DVS_element); else DVS_element := ( c_left => 0.0, a_task => an_event.activation_task, element => 0.0, release_time => current_time ); DVS_map_package.Insert(DVS_map,an_event.activation_task.name,DVS_element); end if; new_frequency_double := select_frequency_static_voltage_scaling(DVS_map); end if; else if scheduler_type = earliest_deadline_first_protocol then if look_ahead_algorithm = True then if DVS_map_package.Contains(DVS_map, an_event.activation_task.name) then DVS_element := ( c_left => (DVS_map_package.Element(DVS_map,an_event.activation_task.name).c_left), a_task => an_event.activation_task, element => (DVS_map_package.Element(DVS_map,an_event.activation_task.name).element), release_time => current_time ); DVS_map_package.Replace(DVS_map,an_event.activation_task.name,DVS_element); look_ahead_task_completion(an_event.activation_task,curr_time_task_exec+1,new_frequency_double); else DVS_element := ( c_left => Double (an_event.activation_task.capacity)/100.0, a_task => an_event.activation_task, element => Double( an_event.activation_task.deadline), release_time => current_time ); DVS_map_package.Insert(DVS_map,an_event.activation_task.name,DVS_element); look_ahead_task_release(an_event.activation_task,current_time, new_frequency_double ); end if; else if DVS_map_package.Contains(DVS_map, an_event.activation_task.name) then DVS_map_package.Replace(DVS_map,an_event.activation_task.name,DVS_element); cycle_conserving_task_completion_edf(an_event.activation_task, new_frequency_double); else DVS_element := ( c_left => 0.0, a_task => an_event.activation_task, element => Double( an_event.activation_task.deadline), release_time => current_time ); DVS_map_package.Insert(DVS_map,an_event.activation_task.name,DVS_element); cycle_conserving_task_release_edf(an_event.activation_task, new_frequency_double); end if; end if; else if scheduler_type = rate_monotonic_protocol then if DVS_map_package.Contains(DVS_map, an_event.activation_task.name) then DVS_element := ( c_left => 0.0, element => 0.0, a_task => (DVS_map_package.Element(DVS_map,an_event.activation_task.name).a_task), release_time => current_time ); DVS_map_package.Replace(DVS_map,an_event.activation_task.name,DVS_element); cycle_conserving_task_completion_rm (an_event.activation_task, curr_time_task_exec, new_frequency_double); else DVS_element := ( c_left => Double (an_event.activation_task.capacity)/100.0, element => Double (an_event.activation_task.capacity)/100.0, a_task => an_event.activation_task, release_time => current_time ); DVS_map_package.Insert(DVS_map,an_event.activation_task.name,DVS_element); fj := select_frequency_static_voltage_scaling(DVS_map); cycle_conserving_task_release_rm(an_event.activation_task,curr_time_task_exec, new_frequency_double ); end if; end if; end if; end if; new_frequency_double_to_integer(new_frequency_double,new_frequency); Put_LINE("Speed: " & Integer 'image(new_frequency)); end dvfs_upon_task_release; procedure dvfs_upon_task_completion (an_event : in time_unit_event_ptr ; current_time : in natural; new_frequency : out integer) is new_frequency_double : Double :=0.0; begin --dvfs_upon_task_completion is never call due to a issue instead we use task_release --if only_static_algorithm = False then Put_LINE("DVFS : task completion"); -- put_line("task name = " & to_string(an_event.end_task.name)); -- Put_LINE("Current_Time " & Natural 'image(current_time)); -- if scheduler_type = earliest_deadline_first_protocol then -- if look_ahead_algorithm then -- look_ahead_task_completion(an_event.end_task,current_time,new_frequency_double); -- else -- cycle_conserving_task_completion_edf(an_event.end_task,new_frequency_double); -- end if; -- else -- if scheduler_type = rate_monotonic_protocol then -- cycle_conserving_task_completion_rm (an_event.end_task, current_time, new_frequency_double); -- end if; -- end if; --end if; --new_frequency_double_to_integer(new_frequency_double,new_frequency); --Put_LINE("Speed: " & Integer 'image(new_frequency)); end dvfs_upon_task_completion; end voltage_scaling;