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

Reply via email to