build { core init timer lib/ld test/cpu_quota } create_boot_directory install_config { } build_boot_image [build_artifacts] append qemu_args "-nographic " run_genode_until ".*done.*\n.*done.*\n.*done.*\n" 110 set err_cnt 0 proc check_counter { name opt cnt total_cnt } { global err_cnt set bad 0 set class "Good:" set tol 0.01 set is 0 # # As we test on QEMU possibly paralell to other activities on the same CPU # we have to consider inconsistencies in timing. # if {[have_include "power_on/qemu"]} { set tol 0.03 } if {[expr $total_cnt != 0]} { set is [expr double($cnt) / $total_cnt ] } set err [expr $is - $opt] set is_fmt [format {%0.3f} [expr $is * 100]] set opt_fmt [format {%0.3f} [expr $opt * 100]] set err_fmt [format {%0.3f} [expr $err * 100]] set tol_fmt [format {%0.3f} [expr $tol * 100]] if {[expr abs($err) > $tol]} { set class "Bad: " set err_cnt [expr $err_cnt + 1] } puts "$class $name received $is_fmt% CPU (goal $opt_fmt% tol $tol_fmt% err $err_fmt%)" } proc check_quota { name opt_sp quota_sp opt_pc quota } { global err_cnt set opt [expr $opt_sp * $opt_pc / 100] set quota_err [expr $quota - $opt] set quota_class "Good:" set sp_class "Good:" # # We tolerate rounding errors up to 0.01% of the super period as the two # quota translations from init to core and then from core to the user are # distinct. # set quota_tol [expr $opt_sp * 1 / 10000] if {[expr abs($quota_err) > $quota_tol]} { set quota_class "Bad: " set err_cnt [expr $err_cnt + 1] } if {[expr $quota_sp != $opt_sp]} { set sp_class "Bad: " set err_cnt [expr $err_cnt + 1] } puts "$quota_class $name has_quota $quota us (goal $opt tol $quota_tol err $quota_err us)" puts "$sp_class $name has super period $quota_sp us (goal $opt_sp us)" } # pre-define variables if regexp does not match set slow_quota ""; set midl_quota ""; set fast_quota "" set slow_quota_sp ""; set midl_quota_sp ""; set fast_quota_sp "" regexp {[0-9]+} [regexp -inline {slow. quota [0-9]+} $output] slow_quota regexp {[0-9]+} [regexp -inline {midl. quota [0-9]+} $output] midl_quota regexp {[0-9]+} [regexp -inline {fast. quota [0-9]+} $output] fast_quota regexp {[0-9]+} [regexp -inline {slow. quota super period [0-9]+} $output] slow_quota_sp regexp {[0-9]+} [regexp -inline {midl. quota super period [0-9]+} $output] midl_quota_sp regexp {[0-9]+} [regexp -inline {fast. quota super period [0-9]+} $output] fast_quota_sp set super_period_us 1000000 check_quota "Slow test" $super_period_us $slow_quota_sp 5 $slow_quota check_quota "Middle test" $super_period_us $midl_quota_sp 20 $midl_quota check_quota "Fast test" $super_period_us $fast_quota_sp 60 $fast_quota regexp {[0-9]+} [regexp -inline {slow. counter A [0-9]+} $output] slow_a_cnt regexp {[0-9]+} [regexp -inline {midl. counter A [0-9]+} $output] midl_a_cnt regexp {[0-9]+} [regexp -inline {fast. counter A [0-9]+} $output] fast_a_cnt regexp {[0-9]+} [regexp -inline {slow. counter B [0-9]+} $output] slow_b_cnt regexp {[0-9]+} [regexp -inline {midl. counter B [0-9]+} $output] midl_b_cnt regexp {[0-9]+} [regexp -inline {fast. counter B [0-9]+} $output] fast_b_cnt set total_cnt [expr $fast_a_cnt + $midl_a_cnt + $slow_a_cnt + $fast_b_cnt + $midl_b_cnt + $slow_b_cnt] # # Slow 5.0 % claim + 5.0 % fill = 10 % # Stage 1 # A 0.5 % claim + 2.5 % fill = 3 % # B 4.5 % claim + 2.5 % fill = 7 % # Stage 2 # A 5.0 % claim + 5.0 % fill = 10 % # Total # A 3/4 * 3 + 1/4 * 10 = 4.75 % # B 3/4 * 7 + 1/4 * 0 = 5.25 % # check_counter "Slow counter A" 0.0475 $slow_a_cnt $total_cnt check_counter "Slow counter B" 0.0525 $slow_b_cnt $total_cnt # # Middle 20 % claim + 5.0 % fill = 25.0 % # Stage 1 # A 2 % claim + 2.5 % fill = 4.5 % # B 18 % claim + 2.5 % fill = 20.5 % # Stage 2 # A 20 % claim + 5.0 % fill = 25.0 % # Total # A 3/4 * 4.5 + 1/4 * 25 = 9.625 % # B 3/4 * 20.5 + 1/4 * 0 = 15.375 % # check_counter "Middle counter A" 0.09625 $midl_a_cnt $total_cnt check_counter "Middle counter B" 0.15375 $midl_b_cnt $total_cnt # # Fast 60 % claim + 5.0 % fill = 65.0 % # Stage 1 # A 6 % claim + 2.5 % fill = 8.5 % # B 54 % claim + 2.5 % fill = 56.5 % # Stage 2 # A 60 % claim + 5.0 % fill = 65.0 % # Total # A 3/4 * 8.5 + 1/4 * 65 = 22.625 % # B 3/4 * 56.5 + 1/4 * 0 = 42.375 % # check_counter "Fast counter A" 0.22625 $fast_a_cnt $total_cnt check_counter "Fast counter B" 0.42375 $fast_b_cnt $total_cnt # final conclusion and return if {[expr $err_cnt > 0]} { puts "Test failed because of $err_cnt errors" exit -1 } puts "Test succeeded"