mirror of
https://github.com/genodelabs/genode.git
synced 2025-05-29 13:44:26 +00:00
timeout test: raise error tolerance on nova + qemu
On QEMU, NOVA uses the pretty unstable TSC emulation as primary time source. Thus, timeouts do not trigger with the common precision (< 50 ms). Use an error tolerance of 200 ms for this platform constellation. Ref #2400
This commit is contained in:
parent
94095a27ac
commit
5fec4a2166
@ -3,17 +3,35 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
#
|
#
|
||||||
# Do not high precision time on ARM with kernels other than HW and on QEMU
|
# Wether the platform allows for timeouts that trigger with a precision < 50 milliseconds
|
||||||
#
|
#
|
||||||
# On ARM, we do not have a component-local hardware time-source. The ARM
|
proc precise_timeouts { } {
|
||||||
# performance counter has no reliable frequency as the ARM idle command
|
|
||||||
# halts the counter. Thus, we do not do local time interpolation on ARM.
|
#
|
||||||
# Except we're on the HW kernel. In this case we can read out the kernel
|
# On QEMU, NOVA uses the pretty unstable TSC emulation as primary time source.
|
||||||
# time instead. On QEMU, the time emulation is not precise enough.
|
#
|
||||||
|
if {[have_include "power_on/qemu"] && [have_spec nova]} { return false }
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
proc high_precision_time { } {
|
# Wether the platform allows for a timestamp that has a precision < 1 millisecond
|
||||||
if {[get_cmd_switch --autopilot] && [have_include "power_on/qemu"]} { return false }
|
#
|
||||||
if {[expr [have_spec arm] && ![have_spec hw]]} { return false }
|
proc precise_time { } {
|
||||||
|
|
||||||
|
#
|
||||||
|
# On QEMU, timing is not stable enough for microseconds precision
|
||||||
|
#
|
||||||
|
if {[have_include "power_on/qemu"]} { return false }
|
||||||
|
|
||||||
|
#
|
||||||
|
# On ARM, we do not have a component-local time source in hardware. The ARM
|
||||||
|
# performance counter has no reliable frequency as the ARM idle command
|
||||||
|
# halts the counter. Thus, we do not use local time interpolation on ARM.
|
||||||
|
# Except we're on the HW kernel. In this case we can read out the kernel
|
||||||
|
# time instead.
|
||||||
|
#
|
||||||
|
if {[expr [have_spec arm] && ![have_spec hw]]} { return false }
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,7 +66,8 @@ append config {
|
|||||||
<start name="test">
|
<start name="test">
|
||||||
<binary name="test-timeout"/>
|
<binary name="test-timeout"/>
|
||||||
<resource name="RAM" quantum="250M"/>
|
<resource name="RAM" quantum="250M"/>
|
||||||
<config high_precision_time="} [high_precision_time] {"/>
|
<config precise_time="} [precise_time] {"
|
||||||
|
precise_timeouts="} [precise_timeouts] {"/>
|
||||||
</start>
|
</start>
|
||||||
</config>
|
</config>
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,6 @@ struct Mixed_timeouts : Test
|
|||||||
|
|
||||||
enum { NR_OF_EVENTS = 20 };
|
enum { NR_OF_EVENTS = 20 };
|
||||||
enum { NR_OF_TIMEOUTS = 4 };
|
enum { NR_OF_TIMEOUTS = 4 };
|
||||||
enum { MAX_ERROR_PC = 10 };
|
|
||||||
|
|
||||||
struct Timeout
|
struct Timeout
|
||||||
{
|
{
|
||||||
@ -126,8 +125,10 @@ struct Mixed_timeouts : Test
|
|||||||
{ &timeouts[2], Duration(Milliseconds(6500)) }
|
{ &timeouts[2], Duration(Milliseconds(6500)) }
|
||||||
};
|
};
|
||||||
|
|
||||||
Duration init_time { Microseconds(0) };
|
Duration init_time { Microseconds(0) };
|
||||||
unsigned event_id { 0 };
|
unsigned event_id { 0 };
|
||||||
|
unsigned long max_error_us { config.xml().attribute_value("precise_timeouts", true) ?
|
||||||
|
50000UL : 200000UL };
|
||||||
|
|
||||||
Timer::Periodic_timeout<Mixed_timeouts> pt1 { timer, *this, &Mixed_timeouts::handle_pt1, timeouts[0].us };
|
Timer::Periodic_timeout<Mixed_timeouts> pt1 { timer, *this, &Mixed_timeouts::handle_pt1, timeouts[0].us };
|
||||||
Timer::Periodic_timeout<Mixed_timeouts> pt2 { timer, *this, &Mixed_timeouts::handle_pt2, timeouts[1].us };
|
Timer::Periodic_timeout<Mixed_timeouts> pt2 { timer, *this, &Mixed_timeouts::handle_pt2, timeouts[1].us };
|
||||||
@ -157,14 +158,12 @@ struct Mixed_timeouts : Test
|
|||||||
unsigned long error_us = max(time_us, event_time_us) -
|
unsigned long error_us = max(time_us, event_time_us) -
|
||||||
min(time_us, event_time_us);
|
min(time_us, event_time_us);
|
||||||
|
|
||||||
float const error_pc = percentage(error_us, timeout.us.value);
|
|
||||||
|
|
||||||
log(time_us / 1000UL, " ms: ", timeout.name, " timeout triggered,"
|
log(time_us / 1000UL, " ms: ", timeout.name, " timeout triggered,"
|
||||||
" error ", error_us, " us (", error_pc, " %)");
|
" error ", error_us, " us (max ", max_error_us, " us)");
|
||||||
|
|
||||||
if (error_pc > MAX_ERROR_PC) {
|
if (error_us > max_error_us) {
|
||||||
|
|
||||||
error("absolute timeout error greater than ", (unsigned)MAX_ERROR_PC, " %");
|
error("absolute timeout error greater than ", (unsigned long)max_error_us, " us");
|
||||||
error_cnt++;
|
error_cnt++;
|
||||||
}
|
}
|
||||||
if (event.timeout && event.timeout != &timeout) {
|
if (event.timeout && event.timeout != &timeout) {
|
||||||
@ -546,10 +545,10 @@ struct Fast_polling : Test
|
|||||||
main_ep(env, STACK_SIZE, "fast_polling_ep"),
|
main_ep(env, STACK_SIZE, "fast_polling_ep"),
|
||||||
main_handler(main_ep, *this, &Fast_polling::main)
|
main_handler(main_ep, *this, &Fast_polling::main)
|
||||||
{
|
{
|
||||||
if (config.xml().attribute_value("high_precision_time", true)) {
|
if (config.xml().attribute_value("precise_time", true)) {
|
||||||
Signal_transmitter(main_handler).submit();
|
Signal_transmitter(main_handler).submit();
|
||||||
} else {
|
} else {
|
||||||
log("... skip test because it requires high precision time");
|
log("... skip test, requires the platform to support precise time");
|
||||||
Test::done.submit();
|
Test::done.submit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user