Module Name: src Committed By: riastradh Date: Sat Jul 8 14:05:51 UTC 2023
Modified Files: src/tests/lib/libc/sys: t_clock_gettime.c Log Message: t_clock_gettime: Add test for PR kern/57512. To generate a diff of this commit: cvs rdiff -u -r1.3 -r1.4 src/tests/lib/libc/sys/t_clock_gettime.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/lib/libc/sys/t_clock_gettime.c diff -u src/tests/lib/libc/sys/t_clock_gettime.c:1.3 src/tests/lib/libc/sys/t_clock_gettime.c:1.4 --- src/tests/lib/libc/sys/t_clock_gettime.c:1.3 Fri Jan 13 21:30:41 2017 +++ src/tests/lib/libc/sys/t_clock_gettime.c Sat Jul 8 14:05:51 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: t_clock_gettime.c,v 1.3 2017/01/13 21:30:41 christos Exp $ */ +/* $NetBSD: t_clock_gettime.c,v 1.4 2023/07/08 14:05:51 riastradh Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -58,17 +58,19 @@ #include <sys/cdefs.h> __COPYRIGHT("@(#) Copyright (c) 2008\ The NetBSD Foundation, inc. All rights reserved."); -__RCSID("$NetBSD: t_clock_gettime.c,v 1.3 2017/01/13 21:30:41 christos Exp $"); +__RCSID("$NetBSD: t_clock_gettime.c,v 1.4 2023/07/08 14:05:51 riastradh Exp $"); #include <sys/param.h> -#include <sys/sysctl.h> +#include <sys/ioctl.h> +#include <sys/sysctl.h> #include <atf-c.h> #include <errno.h> +#include <fcntl.h> #include <limits.h> -#include <stdio.h> #include <stdint.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> @@ -204,10 +206,93 @@ ATF_TC_BODY(clock_gettime_real, tc) RL(sysctlbyname(TC_HARDWARE, NULL, 0, save, strlen(save))); } +static void +waste_user_time(void) +{ + static char buf[4*4096]; + + arc4random_buf(buf, sizeof(buf)); +} + +static void __unused +waste_system_time(void) +{ + static char buf[4*4096]; + int fd[2]; + int i, n; + + RL(pipe2(fd, O_NONBLOCK)); + RL(n = ioctl(fd[1], FIONSPACE)); + n = MIN(MAX(0, n), sizeof(buf)); + for (i = 0; i < 16; i++) { + RL(write(fd[1], buf, n)); + RL(read(fd[0], buf, n)); + } + RL(close(fd[0])); + RL(close(fd[1])); +} + +static void +check_monotonicity(const char *clockname, clockid_t clockid, + void (*waste_time)(void)) +{ + static const struct timespec maxtime = {5, 0}; + struct timespec mono_t0, t0, mono_d; + + RL(clock_gettime(CLOCK_MONOTONIC, &mono_t0)); + RL(clock_gettime(clockid, &t0)); + + do { + struct timespec t1, mono_t1; + + (*waste_time)(); + + RL(clock_gettime(clockid, &t1)); + ATF_CHECK_MSG(timespeccmp(&t0, &t1, <=), + "clock %s=0x%jx went backwards t0=%jd.%09ld t1=%jd.%09ld", + clockname, (uintmax_t)clockid, + (intmax_t)t0.tv_sec, t0.tv_nsec, + (intmax_t)t1.tv_sec, t1.tv_nsec); + + t0 = t1; + + RL(clock_gettime(CLOCK_MONOTONIC, &mono_t1)); + timespecsub(&mono_t1, &mono_t0, &mono_d); + } while (timespeccmp(&mono_d, &maxtime, <)); +} + +ATF_TC(clock_gettime_process_cputime_is_monotonic); +ATF_TC_HEAD(clock_gettime_process_cputime_is_monotonic, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks that CLOCK_PROCESS_CPUTIME_ID is monotonic"); +} +ATF_TC_BODY(clock_gettime_process_cputime_is_monotonic, tc) +{ + check_monotonicity("CLOCK_PROCESS_CPUTIME_ID", + CLOCK_PROCESS_CPUTIME_ID, &waste_user_time); +} + +ATF_TC(clock_gettime_thread_cputime_is_monotonic); +ATF_TC_HEAD(clock_gettime_thread_cputime_is_monotonic, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks that CLOCK_THREAD_CPUTIME_ID is monotonic"); +} +ATF_TC_BODY(clock_gettime_thread_cputime_is_monotonic, tc) +{ + atf_tc_expect_fail("PR kern/57512: clock_gettime" + "(CLOCK_THREAD_CPUTIME_ID) sometimes goes backwards"); + check_monotonicity("CLOCK_THREAD_CPUTIME_ID", + CLOCK_THREAD_CPUTIME_ID, &waste_user_time); +} + ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, clock_gettime_real); + ATF_TP_ADD_TC(tp, clock_gettime_process_cputime_is_monotonic); + ATF_TP_ADD_TC(tp, clock_gettime_thread_cputime_is_monotonic); return atf_no_error(); }