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();
}
}