Module Name: src Committed By: hannken Date: Sun Nov 21 09:35:39 UTC 2021
Modified Files: src/tests/kernel/kqueue: Makefile t_timer.c Log Message: Test kernel/kqueue/t_timer, subtests abstime, basic_timer and timer_units often fail when run on QEMU because QEMU misses clock interrupts. Always check timespec against expected "tv_sec" and use an "4 * tv_sec" upper bound when run under QEMU. Now becomes part of PR kern/43997 "Kernel timer discrepancies". To generate a diff of this commit: cvs rdiff -u -r1.9 -r1.10 src/tests/kernel/kqueue/Makefile cvs rdiff -u -r1.3 -r1.4 src/tests/kernel/kqueue/t_timer.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/tests/kernel/kqueue/Makefile diff -u src/tests/kernel/kqueue/Makefile:1.9 src/tests/kernel/kqueue/Makefile:1.10 --- src/tests/kernel/kqueue/Makefile:1.9 Sat Oct 23 18:46:26 2021 +++ src/tests/kernel/kqueue/Makefile Sun Nov 21 09:35:39 2021 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.9 2021/10/23 18:46:26 thorpej Exp $ +# $NetBSD: Makefile,v 1.10 2021/11/21 09:35:39 hannken Exp $ WARNS?=6 NOMAN= # defined @@ -24,4 +24,6 @@ TESTS_C+= t_vnode LDADD.t_scan+= -lpthread +CPPFLAGS.t_timer.c+= -I${.CURDIR}/../../lib/libc/gen + .include <bsd.test.mk> Index: src/tests/kernel/kqueue/t_timer.c diff -u src/tests/kernel/kqueue/t_timer.c:1.3 src/tests/kernel/kqueue/t_timer.c:1.4 --- src/tests/kernel/kqueue/t_timer.c:1.3 Fri Oct 22 13:53:20 2021 +++ src/tests/kernel/kqueue/t_timer.c Sun Nov 21 09:35:39 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: t_timer.c,v 1.3 2021/10/22 13:53:20 thorpej Exp $ */ +/* $NetBSD: t_timer.c,v 1.4 2021/11/21 09:35:39 hannken Exp $ */ /*- * Copyright (c) 2021 The NetBSD Foundation, Inc. @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: t_timer.c,v 1.3 2021/10/22 13:53:20 thorpej Exp $"); +__RCSID("$NetBSD: t_timer.c,v 1.4 2021/11/21 09:35:39 hannken Exp $"); #include <sys/types.h> #include <sys/event.h> @@ -39,6 +39,36 @@ __RCSID("$NetBSD: t_timer.c,v 1.3 2021/1 #include <atf-c.h> +#include "isqemu.h" + +static bool +check_timespec(struct timespec *ts, time_t seconds) +{ + time_t upper = seconds; + bool result = true; + + /* + * If running under QEMU make sure the upper bound is large + * enough for the effect of kern/43997 + */ + if (isQEMU()) { + upper *= 4; + } + + if (ts->tv_sec < seconds - 1 || + (ts->tv_sec == seconds - 1 && ts->tv_nsec < 500000000)) + result = false; + else if (ts->tv_sec > upper || + (ts->tv_sec == upper && ts->tv_nsec >= 500000000)) + result = false; + + printf("time %" PRId64 ".%09ld %sin [ %" PRId64 ".5, %" PRId64 ".5 )\n", + ts->tv_sec, ts->tv_nsec, (result ? "" : "not "), + seconds - 1, upper); + + return result; +} + ATF_TC(basic_timer); ATF_TC_HEAD(basic_timer, tc) { @@ -83,13 +113,8 @@ ATF_TC_BODY(basic_timer, tc) ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &ts) == 0); timespecsub(&ts, &ots, &ts); - ATF_REQUIRE(ts.tv_sec == - (TIME1_TOTAL_SEC - 1) || - ts.tv_sec == TIME1_TOTAL_SEC); - if (ts.tv_sec == TIME1_TOTAL_SEC - 1) { - ATF_REQUIRE(ts.tv_nsec >= - 900000000); - } + ATF_REQUIRE(check_timespec(&ts, + TIME1_TOTAL_SEC)); EV_SET(&event[0], 1, EVFILT_TIMER, EV_DELETE, 0, 0, NULL); ATF_REQUIRE(kevent(kq, event, 1, NULL, 0, @@ -106,12 +131,7 @@ ATF_TC_BODY(basic_timer, tc) ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &ts) == 0); timespecsub(&ts, &ots, &ts); - ATF_REQUIRE(ts.tv_sec == - (TIME2_TOTAL_SEC - 1) || - ts.tv_sec == TIME2_TOTAL_SEC); - if (ts.tv_sec == TIME2_TOTAL_SEC - 1) { - ATF_REQUIRE(ts.tv_nsec >= 900000000); - } + ATF_REQUIRE(check_timespec(&ts, TIME2_TOTAL_SEC)); EV_SET(&event[0], 2, EVFILT_TIMER, EV_DELETE, 0, 0, NULL); ATF_REQUIRE_ERRNO(ENOENT, @@ -130,14 +150,7 @@ ATF_TC_BODY(basic_timer, tc) ATF_REQUIRE(kevent(kq, NULL, 0, event, 1, &ts) == 0); ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &ts) == 0); timespecsub(&ts, &ots, &ts); - ATF_REQUIRE(ts.tv_sec == (TIME2_TOTAL_SEC - 1) || - ts.tv_sec == TIME2_TOTAL_SEC || - ts.tv_sec == (TIME2_TOTAL_SEC + 1)); - if (ts.tv_sec == TIME2_TOTAL_SEC - 1) { - ATF_REQUIRE(ts.tv_nsec >= 900000000); - } else if (ts.tv_sec == TIME2_TOTAL_SEC + 1) { - ATF_REQUIRE(ts.tv_nsec < 500000000); - } + ATF_REQUIRE(check_timespec(&ts, TIME2_TOTAL_SEC)); } ATF_TC(count_expirations); @@ -272,9 +285,6 @@ ATF_TC_BODY(abstime, tc) ATF_REQUIRE(ots.tv_sec < INTPTR_MAX - TIME1_TOTAL_SEC); seconds = ots.tv_sec + TIME1_TOTAL_SEC; - if (ots.tv_nsec >= 500000000) { - seconds++; - } EV_SET(&event[0], 1, EVFILT_TIMER, EV_ADD, NOTE_ABSTIME | NOTE_SECONDS, seconds, NULL); @@ -287,10 +297,7 @@ ATF_TC_BODY(abstime, tc) * We're not going for precision here; just verify that it was * delivered anywhere between 4.5-6.whatever seconds later. */ - ATF_REQUIRE(ts.tv_sec >= 4 && ts.tv_sec <= 6); - if (ts.tv_sec == 4) { - ATF_REQUIRE(ts.tv_nsec >= 500000000); - } + ATF_REQUIRE(check_timespec(&ts, 4) || check_timespec(&ts, 5)); ts.tv_sec = 0; ts.tv_nsec = 0; @@ -316,13 +323,8 @@ do_test_timer_units(const char *which, u ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &ts) == 0); timespecsub(&ts, &ots, &ts); - ATF_REQUIRE_MSG(ts.tv_sec == (PREC_TIMEOUT_SEC - 1) || - ts.tv_sec == PREC_TIMEOUT_SEC, - "units '%s' failed [sec]", which); - if (ts.tv_sec == PREC_TIMEOUT_SEC - 1) { - ATF_REQUIRE_MSG(ts.tv_nsec >= 900000000, - "units '%s' failed [nsec]", which); - } + ATF_REQUIRE_MSG(check_timespec(&ts, PREC_TIMEOUT_SEC), + "units '%s' failed", which); (void)close(kq); }