mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-21 06:33:31 +00:00
bf62d6b896
Since the timer and timeout handling is part of the base library (the dynamic linker), it belongs to the base repository. Besides moving the timer and its related infrastructure (alarm, timeout libs, tests) to the base repository, this patch also moves the timer from the 'drivers' subdirectory directly to 'src' and disamibuates the timer's build locations for the various kernels. Otherwise the different timer implementations could interfere with each other when using one build directory with multiple kernels. Note that this patch changes the include paths for the former os/timer, os/alarm.h, os/duration.h, and os/timed_semaphore.h to base/. Issue #3101
280 lines
7.6 KiB
Plaintext
280 lines
7.6 KiB
Plaintext
#
|
|
# Check platform
|
|
#
|
|
# HW is the only kernel that provides appliance of quota to the scheduling.
|
|
#
|
|
assert_spec hw
|
|
|
|
#
|
|
# Build
|
|
#
|
|
|
|
build "core init timer test/cpu_quota"
|
|
|
|
#
|
|
# Boot image
|
|
#
|
|
|
|
create_boot_directory
|
|
|
|
install_config {
|
|
<config prio_levels="4">
|
|
<parent-provides>
|
|
<service name="ROM"/>
|
|
<service name="IRQ"/>
|
|
<service name="IO_MEM"/>
|
|
<service name="IO_PORT"/>
|
|
<service name="PD"/>
|
|
<service name="RM"/>
|
|
<service name="CPU"/>
|
|
<service name="LOG"/>
|
|
</parent-provides>
|
|
<default-route>
|
|
<any-service><parent/><any-child/></any-service>
|
|
</default-route>
|
|
|
|
<default caps="100"/>
|
|
|
|
<start name="test-sync">
|
|
<resource name="RAM" quantum="10M"/>
|
|
<provides><service name="Sync"/></provides>
|
|
</start>
|
|
|
|
<start name="init_1" priority="-1" caps="1000">
|
|
<binary name="init"/>
|
|
<resource name="RAM" quantum="20M"/>
|
|
<resource name="CPU" quantum="10"/>
|
|
<config>
|
|
<parent-provides>
|
|
<service name="ROM"/>
|
|
<service name="IRQ"/>
|
|
<service name="IO_MEM"/>
|
|
<service name="IO_PORT"/>
|
|
<service name="PD"/>
|
|
<service name="RM"/>
|
|
<service name="CPU"/>
|
|
<service name="LOG"/>
|
|
<service name="Timer"/>
|
|
<service name="Sync"/>
|
|
</parent-provides>
|
|
<default-route>
|
|
<any-service><parent/><any-child/></any-service>
|
|
</default-route>
|
|
<default caps="100"/>
|
|
|
|
<start name="test_slow">
|
|
<binary name="test-cpu_quota"/>
|
|
<resource name="RAM" quantum="10M"/>
|
|
<resource name="CPU" quantum="50"/>
|
|
</start>
|
|
|
|
</config>
|
|
</start>
|
|
|
|
<start name="init_2" priority="-2" caps="1000">
|
|
<binary name="init"/>
|
|
<resource name="RAM" quantum="30M"/>
|
|
<resource name="CPU" quantum="80"/>
|
|
<config prio_levels="2">
|
|
<parent-provides>
|
|
<service name="ROM"/>
|
|
<service name="IRQ"/>
|
|
<service name="IO_MEM"/>
|
|
<service name="IO_PORT"/>
|
|
<service name="PD"/>
|
|
<service name="RM"/>
|
|
<service name="CPU"/>
|
|
<service name="LOG"/>
|
|
<service name="Timer"/>
|
|
<service name="Sync"/>
|
|
</parent-provides>
|
|
<default-route>
|
|
<any-service><parent/></any-service>
|
|
</default-route>
|
|
|
|
<default caps="100"/>
|
|
|
|
<start name="test_midl" priority="0">
|
|
<binary name="test-cpu_quota"/>
|
|
<resource name="RAM" quantum="10M"/>
|
|
<resource name="CPU" quantum="25"/>
|
|
</start>
|
|
|
|
<start name="test_fast" priority="-1">
|
|
<binary name="test-cpu_quota"/>
|
|
<resource name="RAM" quantum="10M"/>
|
|
<resource name="CPU" quantum="75"/>
|
|
</start>
|
|
|
|
</config>
|
|
</start>
|
|
|
|
<start name="timer" priority="0">
|
|
<resource name="RAM" quantum="10M"/>
|
|
<resource name="CPU" quantum="10"/>
|
|
<provides><service name="Timer"/></provides>
|
|
</start>
|
|
|
|
</config>
|
|
}
|
|
|
|
build_boot_image "core ld.lib.so init timer test-cpu_quota test-sync"
|
|
|
|
#
|
|
# Execution
|
|
#
|
|
|
|
append qemu_args "-nographic "
|
|
|
|
run_genode_until ".*done.*\n.*done.*\n.*done.*\n" 110
|
|
|
|
#
|
|
# Conclusion
|
|
#
|
|
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 }
|
|
|
|
#
|
|
# FIXME: There is no reasonable explanation by now why the test results
|
|
# are less stable on these platforms. We have tried several things that
|
|
# did not lead to an explanation or improvement:
|
|
#
|
|
# * changing the timing parameters of the scheduler
|
|
# * switching off SMP
|
|
# * double-checking the speed of userland and kernel timers
|
|
#
|
|
if {[have_spec odroid_xu]} { set tol 0.04 }
|
|
if {[have_spec arndale]} { set tol 0.04 }
|
|
|
|
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"
|