From 5fec4a21665f736cd36f4dd08e21e99e5d13593d Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Fri, 16 Jun 2017 14:49:24 +0200 Subject: [PATCH] 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 --- repos/os/run/timeout.run | 39 +++++++++++++++++++++++-------- repos/os/src/test/timeout/main.cc | 19 +++++++-------- 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/repos/os/run/timeout.run b/repos/os/run/timeout.run index 38262de208..462e55a7f1 100644 --- a/repos/os/run/timeout.run +++ b/repos/os/run/timeout.run @@ -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 -# 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 -# time instead. On QEMU, the time emulation is not precise enough. +proc precise_timeouts { } { + + # + # On QEMU, NOVA uses the pretty unstable TSC emulation as primary time source. + # + if {[have_include "power_on/qemu"] && [have_spec nova]} { return false } + return true +} + # -proc high_precision_time { } { - if {[get_cmd_switch --autopilot] && [have_include "power_on/qemu"]} { return false } - if {[expr [have_spec arm] && ![have_spec hw]]} { return false } +# Wether the platform allows for a timestamp that has a precision < 1 millisecond +# +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 } @@ -48,7 +66,8 @@ append config { - + } diff --git a/repos/os/src/test/timeout/main.cc b/repos/os/src/test/timeout/main.cc index 3fc1883f5d..88936d3514 100644 --- a/repos/os/src/test/timeout/main.cc +++ b/repos/os/src/test/timeout/main.cc @@ -72,7 +72,6 @@ struct Mixed_timeouts : Test enum { NR_OF_EVENTS = 20 }; enum { NR_OF_TIMEOUTS = 4 }; - enum { MAX_ERROR_PC = 10 }; struct Timeout { @@ -126,8 +125,10 @@ struct Mixed_timeouts : Test { &timeouts[2], Duration(Milliseconds(6500)) } }; - Duration init_time { Microseconds(0) }; - unsigned event_id { 0 }; + Duration init_time { Microseconds(0) }; + unsigned event_id { 0 }; + unsigned long max_error_us { config.xml().attribute_value("precise_timeouts", true) ? + 50000UL : 200000UL }; Timer::Periodic_timeout pt1 { timer, *this, &Mixed_timeouts::handle_pt1, timeouts[0].us }; Timer::Periodic_timeout 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) - 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," - " 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++; } if (event.timeout && event.timeout != &timeout) { @@ -546,10 +545,10 @@ struct Fast_polling : Test main_ep(env, STACK_SIZE, "fast_polling_ep"), 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(); } else { - log("... skip test because it requires high precision time"); + log("... skip test, requires the platform to support precise time"); Test::done.submit(); } }