xref: /netbsd-src/tests/kernel/t_time_arith.c (revision faf3bea1422fb86b481b6b57a9907d22e5c3f1b2)
1*faf3bea1Sriastradh /*	$NetBSD: t_time_arith.c,v 1.1 2024/12/22 23:25:15 riastradh Exp $	*/
2*faf3bea1Sriastradh 
3*faf3bea1Sriastradh /*-
4*faf3bea1Sriastradh  * Copyright (c) 2024 The NetBSD Foundation, Inc.
5*faf3bea1Sriastradh  * All rights reserved.
6*faf3bea1Sriastradh  *
7*faf3bea1Sriastradh  * Redistribution and use in source and binary forms, with or without
8*faf3bea1Sriastradh  * modification, are permitted provided that the following conditions
9*faf3bea1Sriastradh  * are met:
10*faf3bea1Sriastradh  * 1. Redistributions of source code must retain the above copyright
11*faf3bea1Sriastradh  *    notice, this list of conditions and the following disclaimer.
12*faf3bea1Sriastradh  * 2. Redistributions in binary form must reproduce the above copyright
13*faf3bea1Sriastradh  *    notice, this list of conditions and the following disclaimer in the
14*faf3bea1Sriastradh  *    documentation and/or other materials provided with the distribution.
15*faf3bea1Sriastradh  *
16*faf3bea1Sriastradh  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17*faf3bea1Sriastradh  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18*faf3bea1Sriastradh  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19*faf3bea1Sriastradh  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20*faf3bea1Sriastradh  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*faf3bea1Sriastradh  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*faf3bea1Sriastradh  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*faf3bea1Sriastradh  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*faf3bea1Sriastradh  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*faf3bea1Sriastradh  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*faf3bea1Sriastradh  * POSSIBILITY OF SUCH DAMAGE.
27*faf3bea1Sriastradh  */
28*faf3bea1Sriastradh 
29*faf3bea1Sriastradh #include <sys/cdefs.h>
30*faf3bea1Sriastradh __RCSID("$NetBSD: t_time_arith.c,v 1.1 2024/12/22 23:25:15 riastradh Exp $");
31*faf3bea1Sriastradh 
32*faf3bea1Sriastradh #include <sys/timearith.h>
33*faf3bea1Sriastradh 
34*faf3bea1Sriastradh #include <atf-c.h>
35*faf3bea1Sriastradh #include <errno.h>
36*faf3bea1Sriastradh #include <limits.h>
37*faf3bea1Sriastradh #include <setjmp.h>
38*faf3bea1Sriastradh #include <signal.h>
39*faf3bea1Sriastradh #include <stdbool.h>
40*faf3bea1Sriastradh #include <stdint.h>
41*faf3bea1Sriastradh #include <stdio.h>
42*faf3bea1Sriastradh #include <stdlib.h>
43*faf3bea1Sriastradh #include <string.h>
44*faf3bea1Sriastradh #include <time.h>
45*faf3bea1Sriastradh #include <unistd.h>
46*faf3bea1Sriastradh #include <util.h>
47*faf3bea1Sriastradh 
48*faf3bea1Sriastradh #include "h_macros.h"
49*faf3bea1Sriastradh 
50*faf3bea1Sriastradh enum { HZ = 100 };
51*faf3bea1Sriastradh 
52*faf3bea1Sriastradh int hz = HZ;
53*faf3bea1Sriastradh int tick = 1000000/HZ;
54*faf3bea1Sriastradh 
55*faf3bea1Sriastradh static sig_atomic_t jmp_en;
56*faf3bea1Sriastradh static int jmp_sig;
57*faf3bea1Sriastradh static jmp_buf jmp;
58*faf3bea1Sriastradh 
59*faf3bea1Sriastradh static void
60*faf3bea1Sriastradh handle_signal(int signo)
61*faf3bea1Sriastradh {
62*faf3bea1Sriastradh 	const int errno_save = errno;
63*faf3bea1Sriastradh 	char buf[32];
64*faf3bea1Sriastradh 
65*faf3bea1Sriastradh 	snprintf_ss(buf, sizeof(buf), "signal %d\n", signo);
66*faf3bea1Sriastradh 	(void)write(STDERR_FILENO, buf, strlen(buf));
67*faf3bea1Sriastradh 
68*faf3bea1Sriastradh 	errno = errno_save;
69*faf3bea1Sriastradh 
70*faf3bea1Sriastradh 	if (jmp_en) {
71*faf3bea1Sriastradh 		jmp_sig = signo;
72*faf3bea1Sriastradh 		jmp_en = 0;
73*faf3bea1Sriastradh 		longjmp(jmp, 1);
74*faf3bea1Sriastradh 	} else {
75*faf3bea1Sriastradh 		raise_default_signal(signo);
76*faf3bea1Sriastradh 	}
77*faf3bea1Sriastradh }
78*faf3bea1Sriastradh 
79*faf3bea1Sriastradh const struct itimer_transition {
80*faf3bea1Sriastradh 	struct itimerspec	it_time;
81*faf3bea1Sriastradh 	struct timespec		it_now;
82*faf3bea1Sriastradh 	struct timespec		it_next;
83*faf3bea1Sriastradh 	int			it_overruns;
84*faf3bea1Sriastradh 	const char		*it_xfail;
85*faf3bea1Sriastradh } itimer_transitions[] = {
86*faf3bea1Sriastradh 	/*
87*faf3bea1Sriastradh 	 * Fired more than one interval early -- treat clock as wound
88*faf3bea1Sriastradh 	 * backwards, not counting overruns.  Advance by somewhere
89*faf3bea1Sriastradh 	 * between one and two intervals from now.
90*faf3bea1Sriastradh 	 */
91*faf3bea1Sriastradh 	[0] = {{.it_value = {3,0}, .it_interval = {1,0}},
92*faf3bea1Sriastradh 	       {0,1}, {2,0}, 0,
93*faf3bea1Sriastradh 	       /* 1.709551617 */
94*faf3bea1Sriastradh 	       "PR kern/58925: itimer(9) responds erratically to clock wound back"},
95*faf3bea1Sriastradh 	[1] = {{.it_value = {3,0}, .it_interval = {1,0}},
96*faf3bea1Sriastradh 	       {0,500000000}, {2,0}, 0,
97*faf3bea1Sriastradh 	       /* 1.709551615 */
98*faf3bea1Sriastradh 	       "PR kern/58925: itimer(9) responds erratically to clock wound back"},
99*faf3bea1Sriastradh 	[2] = {{.it_value = {3,0}, .it_interval = {1,0}},
100*faf3bea1Sriastradh 	       {0,999999999}, {2,0}, 0,
101*faf3bea1Sriastradh 	       /* 2.709551613 */
102*faf3bea1Sriastradh 	       "PR kern/58925: itimer(9) responds erratically to clock wound back"},
103*faf3bea1Sriastradh 	[3] = {{.it_value = {3,0}, .it_interval = {1,0}},
104*faf3bea1Sriastradh 	       {1,0}, {2,0}, 0,
105*faf3bea1Sriastradh 	       /* 2.709551615 */
106*faf3bea1Sriastradh 	       "PR kern/58925: itimer(9) responds erratically to clock wound back"},
107*faf3bea1Sriastradh 	[4] = {{.it_value = {3,0}, .it_interval = {1,0}},
108*faf3bea1Sriastradh 	       {1,1}, {3,0}, 0,
109*faf3bea1Sriastradh 	       /* 2.709551617 */
110*faf3bea1Sriastradh 	       "PR kern/58925: itimer(9) responds erratically to clock wound back"},
111*faf3bea1Sriastradh 	[5] = {{.it_value = {3,0}, .it_interval = {1,0}},
112*faf3bea1Sriastradh 	       {1,500000000}, {3,0}, 0,
113*faf3bea1Sriastradh 	       /* 2.709551615 */
114*faf3bea1Sriastradh 	       "PR kern/58925: itimer(9) responds erratically to clock wound back"},
115*faf3bea1Sriastradh 	[6] = {{.it_value = {3,0}, .it_interval = {1,0}},
116*faf3bea1Sriastradh 	       {1,999999999}, {3,0}, 0,
117*faf3bea1Sriastradh 	       /* 3.709551613 */
118*faf3bea1Sriastradh 	       "PR kern/58925: itimer(9) responds erratically to clock wound back"},
119*faf3bea1Sriastradh 
120*faf3bea1Sriastradh 	/*
121*faf3bea1Sriastradh 	 * Fired exactly one interval early.  Treat this too as clock
122*faf3bea1Sriastradh 	 * wound backwards.
123*faf3bea1Sriastradh 	 */
124*faf3bea1Sriastradh 	[7] = {{.it_value = {3,0}, .it_interval = {1,0}},
125*faf3bea1Sriastradh 	       {2,0}, {3,0}, 0,
126*faf3bea1Sriastradh 	       /* 3.709551615 */
127*faf3bea1Sriastradh 	       "PR kern/58925: itimer(9) responds erratically to clock wound back"},
128*faf3bea1Sriastradh 
129*faf3bea1Sriastradh 	/*
130*faf3bea1Sriastradh 	 * Fired less than one interval early -- callouts and real-time
131*faf3bea1Sriastradh 	 * clock might not be perfectly synced, counted as zero
132*faf3bea1Sriastradh 	 * overruns.  Advance by one interval from the scheduled time.
133*faf3bea1Sriastradh 	 */
134*faf3bea1Sriastradh 	[8] = {{.it_value = {3,0}, .it_interval = {1,0}},
135*faf3bea1Sriastradh 	       {2,1}, {4,0}, 0,
136*faf3bea1Sriastradh 	       /* 3.000000001 */
137*faf3bea1Sriastradh 	       "PR kern/58925: itimer(9) responds erratically to clock wound back"},
138*faf3bea1Sriastradh 	[9] = {{.it_value = {3,0}, .it_interval = {1,0}},
139*faf3bea1Sriastradh 	       {2,500000000}, {4,0}, 0,
140*faf3bea1Sriastradh 	       /* 3.999999999 */
141*faf3bea1Sriastradh 	       "PR kern/58925: itimer(9) responds erratically to clock wound back"},
142*faf3bea1Sriastradh 	[10] = {{.it_value = {3,0}, .it_interval = {1,0}},
143*faf3bea1Sriastradh 		{2,999999999}, {4,0}, 0,
144*faf3bea1Sriastradh 		/* 4.999999997 */
145*faf3bea1Sriastradh 		"PR kern/58925: itimer(9) responds erratically to clock wound back"},
146*faf3bea1Sriastradh 
147*faf3bea1Sriastradh 	/*
148*faf3bea1Sriastradh 	 * Fired exactly on time.  Advance by one interval.
149*faf3bea1Sriastradh 	 */
150*faf3bea1Sriastradh 	[11] = {{.it_value = {3,0}, .it_interval = {1,0}},
151*faf3bea1Sriastradh 		{3,0}, {4,0}, 0, NULL},
152*faf3bea1Sriastradh 
153*faf3bea1Sriastradh 	/*
154*faf3bea1Sriastradh 	 * Fired late by less than one interval -- callouts and
155*faf3bea1Sriastradh 	 * real-time clock might not be prefectly synced, counted as
156*faf3bea1Sriastradh 	 * zero overruns.  Advance by one interval from the scheduled
157*faf3bea1Sriastradh 	 * time (even if it's very close to a full interval).
158*faf3bea1Sriastradh 	 */
159*faf3bea1Sriastradh 	[12] = {{.it_value = {3,0}, .it_interval = {1,0}},
160*faf3bea1Sriastradh 		{3,1}, {4,0}, 0, NULL},
161*faf3bea1Sriastradh 	[14] = {{.it_value = {3,0}, .it_interval = {1,0}},
162*faf3bea1Sriastradh 		{3,500000000}, {4,0}, 0, NULL},
163*faf3bea1Sriastradh 	[15] = {{.it_value = {3,0}, .it_interval = {1,0}},
164*faf3bea1Sriastradh 		{3,999999999}, {4,0}, 0, NULL},
165*faf3bea1Sriastradh 
166*faf3bea1Sriastradh 	/*
167*faf3bea1Sriastradh 	 * Fired late by exactly one interval -- treat it as overrun.
168*faf3bea1Sriastradh 	 *
169*faf3bea1Sriastradh 	 * XXX ...or treat it as not overrun?  wat
170*faf3bea1Sriastradh 	 */
171*faf3bea1Sriastradh 	[16] = {{.it_value = {3,0}, .it_interval = {1,0}},
172*faf3bea1Sriastradh 		{4,0}, {4,0}, 0, NULL},
173*faf3bea1Sriastradh 
174*faf3bea1Sriastradh 	/*
175*faf3bea1Sriastradh 	 * Fired late by more than one interval but less than two --
176*faf3bea1Sriastradh 	 * overrun.
177*faf3bea1Sriastradh 	 */
178*faf3bea1Sriastradh 	[17] = {{.it_value = {3,0}, .it_interval = {1,0}},
179*faf3bea1Sriastradh 		{4,1}, {5,0}, 1,
180*faf3bea1Sriastradh 		/* 4.000000000, overruns=0 */
181*faf3bea1Sriastradh 		"PR kern/58927: itimer(9): overrun accounting is broken"},
182*faf3bea1Sriastradh 	[18] = {{.it_value = {3,0}, .it_interval = {1,0}},
183*faf3bea1Sriastradh 		{4,500000000}, {5,0}, 1,
184*faf3bea1Sriastradh 		/* 4.000000000, overruns=0 */
185*faf3bea1Sriastradh 		"PR kern/58927: itimer(9): overrun accounting is broken"},
186*faf3bea1Sriastradh 	[19] = {{.it_value = {3,0}, .it_interval = {1,0}},
187*faf3bea1Sriastradh 		{4,999999999}, {5,0}, 1,
188*faf3bea1Sriastradh 		/* 4.000000000, overruns=0 */
189*faf3bea1Sriastradh 		"PR kern/58927: itimer(9): overrun accounting is broken"},
190*faf3bea1Sriastradh 
191*faf3bea1Sriastradh 	/*
192*faf3bea1Sriastradh 	 * Fired late by exactly two intervals -- two overruns.
193*faf3bea1Sriastradh 	 */
194*faf3bea1Sriastradh 	[20] = {{.it_value = {3,0}, .it_interval = {1,0}},
195*faf3bea1Sriastradh 		{5,0}, {6,0}, 2,
196*faf3bea1Sriastradh 		/* 4.000000000, overruns=0 */
197*faf3bea1Sriastradh 		"PR kern/58927: itimer(9): overrun accounting is broken"},
198*faf3bea1Sriastradh 
199*faf3bea1Sriastradh 	/*
200*faf3bea1Sriastradh 	 * Fired late by more intervals plus slop, up to 32.
201*faf3bea1Sriastradh 	 *
202*faf3bea1Sriastradh 	 * XXX Define DELAYTIMER_MAX so we can write it in terms of
203*faf3bea1Sriastradh 	 * that.
204*faf3bea1Sriastradh 	 */
205*faf3bea1Sriastradh 	[21] = {{.it_value = {3,0}, .it_interval = {1,0}},
206*faf3bea1Sriastradh 		{13,123456789}, {14,0}, 10,
207*faf3bea1Sriastradh 		/* 4.000000000, overruns=0 */
208*faf3bea1Sriastradh 		"PR kern/58927: itimer(9): overrun accounting is broken"},
209*faf3bea1Sriastradh 	[22] = {{.it_value = {3,0}, .it_interval = {1,0}},
210*faf3bea1Sriastradh 		{34,999999999}, {32,0}, 32,
211*faf3bea1Sriastradh 		/* 4.000000000, overruns=0 */
212*faf3bea1Sriastradh 		"PR kern/58927: itimer(9): overrun accounting is broken"},
213*faf3bea1Sriastradh 
214*faf3bea1Sriastradh 	/*
215*faf3bea1Sriastradh 	 * Fired late by roughly INT_MAX intervals.
216*faf3bea1Sriastradh 	 */
217*faf3bea1Sriastradh 	[23] = {{.it_value = {3,0}, .it_interval = {1,0}},
218*faf3bea1Sriastradh 		{(time_t)3 + INT_MAX - 1, 0},
219*faf3bea1Sriastradh 		{(time_t)3 + INT_MAX, 0},
220*faf3bea1Sriastradh 		INT_MAX,
221*faf3bea1Sriastradh 		/* 4.000000000, overruns=0 */
222*faf3bea1Sriastradh 		"PR kern/58927: itimer(9): overrun accounting is broken"},
223*faf3bea1Sriastradh 	[24] = {{.it_value = {3,0}, .it_interval = {1,0}},
224*faf3bea1Sriastradh 		{(time_t)3 + INT_MAX, 0},
225*faf3bea1Sriastradh 		{(time_t)3 + INT_MAX + 1, 0},
226*faf3bea1Sriastradh 		INT_MAX,
227*faf3bea1Sriastradh 		/* 4.000000000, overruns=0 */
228*faf3bea1Sriastradh 		"PR kern/58926: itimer(9) integer overflow in overrun counting"},
229*faf3bea1Sriastradh 	[25] = {{.it_value = {3,0}, .it_interval = {1,0}},
230*faf3bea1Sriastradh 		{(time_t)3 + INT_MAX + 1, 0},
231*faf3bea1Sriastradh 		{(time_t)3 + INT_MAX + 2, 0},
232*faf3bea1Sriastradh 		INT_MAX,
233*faf3bea1Sriastradh 		/* 4.000000000, overruns=0 */
234*faf3bea1Sriastradh 		"PR kern/58926: itimer(9) integer overflow in overrun counting"},
235*faf3bea1Sriastradh 
236*faf3bea1Sriastradh 	/* (2^63 - 1) ns */
237*faf3bea1Sriastradh 	[26] = {{.it_value = {3,0}, .it_interval = {9223372036,854775807}},
238*faf3bea1Sriastradh 		{3,1}, {9223372039,854775807}, 0, NULL},
239*faf3bea1Sriastradh 	/* 2^63 ns */
240*faf3bea1Sriastradh 	[27] = {{.it_value = {3,0}, .it_interval = {9223372036,854775808}},
241*faf3bea1Sriastradh 		{3,1}, {9223372039,854775808}, 0, NULL},
242*faf3bea1Sriastradh 	/* (2^63 + 1) ns */
243*faf3bea1Sriastradh 	[28] = {{.it_value = {3,0}, .it_interval = {9223372036,854775809}},
244*faf3bea1Sriastradh 		{3,1}, {9223372039,854775809}, 0, NULL},
245*faf3bea1Sriastradh 
246*faf3bea1Sriastradh 	/*
247*faf3bea1Sriastradh 	 * Overflows -- we should (XXX but currently don't) reject
248*faf3bea1Sriastradh 	 * intervals of at least 2^64 nanoseconds up front, since this
249*faf3bea1Sriastradh 	 * is more time than it is reasonable to wait (more than 584
250*faf3bea1Sriastradh 	 * years).
251*faf3bea1Sriastradh 	 */
252*faf3bea1Sriastradh 
253*faf3bea1Sriastradh 	/* (2^64 - 1) ns */
254*faf3bea1Sriastradh 	[29] = {{.it_value = {3,0}, .it_interval = {18446744073,709551615}},
255*faf3bea1Sriastradh 		{2,999999999}, {0,0}, 0,
256*faf3bea1Sriastradh 		"PR kern/58922: itimer(9): arithmetic overflow"},
257*faf3bea1Sriastradh 	/* 2^64 ns */
258*faf3bea1Sriastradh 	[30] = {{.it_value = {3,0}, .it_interval = {18446744073,709551616}},
259*faf3bea1Sriastradh 		{2,999999999}, {0,0}, 0,
260*faf3bea1Sriastradh 		"PR kern/58922: itimer(9): arithmetic overflow"},
261*faf3bea1Sriastradh 	/* (2^64 + 1) ns */
262*faf3bea1Sriastradh 	[31] = {{.it_value = {3,0}, .it_interval = {18446744073,709551617}},
263*faf3bea1Sriastradh 		{2,999999999}, {0,0}, 0,
264*faf3bea1Sriastradh 		"PR kern/58922: itimer(9): arithmetic overflow"},
265*faf3bea1Sriastradh 
266*faf3bea1Sriastradh 	/* (2^63 - 1) us */
267*faf3bea1Sriastradh 	[32] = {{.it_value = {3,0}, .it_interval = {9223372036854,775807}},
268*faf3bea1Sriastradh 		{2,999999999}, {0,0}, 0,
269*faf3bea1Sriastradh 		"PR kern/58922: itimer(9): arithmetic overflow"},
270*faf3bea1Sriastradh 	/* 2^63 us */
271*faf3bea1Sriastradh 	[33] = {{.it_value = {3,0}, .it_interval = {9223372036854,775808}},
272*faf3bea1Sriastradh 		{2,999999999}, {0,0}, 0,
273*faf3bea1Sriastradh 		"PR kern/58922: itimer(9): arithmetic overflow"},
274*faf3bea1Sriastradh 	/* (2^63 + 1) us */
275*faf3bea1Sriastradh 	[34] = {{.it_value = {3,0}, .it_interval = {9223372036854,775809}},
276*faf3bea1Sriastradh 		{2,999999999}, {0,0}, 0,
277*faf3bea1Sriastradh 		"PR kern/58922: itimer(9): arithmetic overflow"},
278*faf3bea1Sriastradh 
279*faf3bea1Sriastradh 	/* (2^64 - 1) us */
280*faf3bea1Sriastradh 	[35] = {{.it_value = {3,0}, .it_interval = {18446744073709,551615}},
281*faf3bea1Sriastradh 		{2,999999999}, {0,0}, 0,
282*faf3bea1Sriastradh 		"PR kern/58922: itimer(9): arithmetic overflow"},
283*faf3bea1Sriastradh 	/* 2^64 us */
284*faf3bea1Sriastradh 	[36] = {{.it_value = {3,0}, .it_interval = {18446744073709,551616}},
285*faf3bea1Sriastradh 		{2,999999999}, {0,0}, 0,
286*faf3bea1Sriastradh 		"PR kern/58922: itimer(9): arithmetic overflow"},
287*faf3bea1Sriastradh 	/* (2^64 + 1) us */
288*faf3bea1Sriastradh 	[37] = {{.it_value = {3,0}, .it_interval = {18446744073709,551617}},
289*faf3bea1Sriastradh 		{2,999999999}, {0,0}, 0,
290*faf3bea1Sriastradh 		"PR kern/58922: itimer(9): arithmetic overflow"},
291*faf3bea1Sriastradh 
292*faf3bea1Sriastradh 	/* (2^63 - 1) ms */
293*faf3bea1Sriastradh 	[38] = {{.it_value = {3,0}, .it_interval = {9223372036854775,807}},
294*faf3bea1Sriastradh 		{2,999999999}, {0,0}, 0,
295*faf3bea1Sriastradh 		"PR kern/58922: itimer(9): arithmetic overflow"},
296*faf3bea1Sriastradh 	/* 2^63 ms */
297*faf3bea1Sriastradh 	[39] = {{.it_value = {3,0}, .it_interval = {9223372036854775,808}},
298*faf3bea1Sriastradh 		{2,999999999}, {0,0}, 0,
299*faf3bea1Sriastradh 		"PR kern/58922: itimer(9): arithmetic overflow"},
300*faf3bea1Sriastradh 	/* (2^63 + 1) ms */
301*faf3bea1Sriastradh 	[40] = {{.it_value = {3,0}, .it_interval = {9223372036854775,809}},
302*faf3bea1Sriastradh 		{2,999999999}, {0,0}, 0,
303*faf3bea1Sriastradh 		"PR kern/58922: itimer(9): arithmetic overflow"},
304*faf3bea1Sriastradh 
305*faf3bea1Sriastradh 	/* (2^64 - 1) ms */
306*faf3bea1Sriastradh 	[41] = {{.it_value = {3,0}, .it_interval = {18446744073709551,615}},
307*faf3bea1Sriastradh 		{2,999999999}, {0,0}, 0,
308*faf3bea1Sriastradh 		"PR kern/58922: itimer(9): arithmetic overflow"},
309*faf3bea1Sriastradh 	/* 2^64 ms */
310*faf3bea1Sriastradh 	[42] = {{.it_value = {3,0}, .it_interval = {18446744073709551,616}},
311*faf3bea1Sriastradh 		{2,999999999}, {0,0}, 0,
312*faf3bea1Sriastradh 		"PR kern/58922: itimer(9): arithmetic overflow"},
313*faf3bea1Sriastradh 	/* (2^64 + 1) ms */
314*faf3bea1Sriastradh 	[43] = {{.it_value = {3,0}, .it_interval = {18446744073709551,617}},
315*faf3bea1Sriastradh 		{2,999999999}, {0,0}, 0,
316*faf3bea1Sriastradh 		"PR kern/58922: itimer(9): arithmetic overflow"},
317*faf3bea1Sriastradh 
318*faf3bea1Sriastradh 	/* invalid intervals */
319*faf3bea1Sriastradh 	[44] = {{.it_value = {3,0}, .it_interval = {-1,0}},
320*faf3bea1Sriastradh 		{3,1}, {0,0}, 0, NULL},
321*faf3bea1Sriastradh 	[45] = {{.it_value = {3,0}, .it_interval = {0,-1}},
322*faf3bea1Sriastradh 		{3,1}, {0,0}, 0, NULL},
323*faf3bea1Sriastradh 	[46] = {{.it_value = {3,0}, .it_interval = {0,1000000000}},
324*faf3bea1Sriastradh 		{3,1}, {0,0}, 0, NULL},
325*faf3bea1Sriastradh };
326*faf3bea1Sriastradh 
327*faf3bea1Sriastradh ATF_TC(itimer_transitions);
328*faf3bea1Sriastradh ATF_TC_HEAD(itimer_transitions, tc)
329*faf3bea1Sriastradh {
330*faf3bea1Sriastradh 	atf_tc_set_md_var(tc, "descr",
331*faf3bea1Sriastradh 	    "Tests interval timer transitions");
332*faf3bea1Sriastradh }
333*faf3bea1Sriastradh ATF_TC_BODY(itimer_transitions, tc)
334*faf3bea1Sriastradh {
335*faf3bea1Sriastradh 	volatile unsigned i;
336*faf3bea1Sriastradh 
337*faf3bea1Sriastradh 	REQUIRE_LIBC(signal(SIGFPE, handle_signal), SIG_ERR);
338*faf3bea1Sriastradh 	REQUIRE_LIBC(signal(SIGABRT, handle_signal), SIG_ERR);
339*faf3bea1Sriastradh 
340*faf3bea1Sriastradh 	for (i = 0; i < __arraycount(itimer_transitions); i++) {
341*faf3bea1Sriastradh 		struct itimer_transition it = itimer_transitions[i];
342*faf3bea1Sriastradh 		struct timespec next;
343*faf3bea1Sriastradh 		int overruns;
344*faf3bea1Sriastradh 		volatile bool aborted = true;
345*faf3bea1Sriastradh 		volatile bool expect_abort = false;
346*faf3bea1Sriastradh 
347*faf3bea1Sriastradh 		fprintf(stderr, "case %u\n", i);
348*faf3bea1Sriastradh 
349*faf3bea1Sriastradh 		if (it.it_xfail)
350*faf3bea1Sriastradh 			atf_tc_expect_fail("%s", it.it_xfail);
351*faf3bea1Sriastradh 
352*faf3bea1Sriastradh 		if (itimespecfix(&it.it_time.it_value) != 0 ||
353*faf3bea1Sriastradh 		    itimespecfix(&it.it_time.it_interval) != 0) {
354*faf3bea1Sriastradh 			fprintf(stderr, "rejected by itimerspecfix\n");
355*faf3bea1Sriastradh 			expect_abort = true;
356*faf3bea1Sriastradh 		}
357*faf3bea1Sriastradh 
358*faf3bea1Sriastradh 		if (setjmp(jmp) == 0) {
359*faf3bea1Sriastradh 			jmp_en = 1;
360*faf3bea1Sriastradh 			itimer_transition(&it.it_time, &it.it_now,
361*faf3bea1Sriastradh 			    &next, &overruns);
362*faf3bea1Sriastradh 			jmp_en = 0;
363*faf3bea1Sriastradh 			aborted = false;
364*faf3bea1Sriastradh 		}
365*faf3bea1Sriastradh 		ATF_CHECK(!jmp_en);
366*faf3bea1Sriastradh 		jmp_en = 0;	/* paranoia */
367*faf3bea1Sriastradh 		if (expect_abort) {
368*faf3bea1Sriastradh 			fprintf(stderr, "expected abort\n");
369*faf3bea1Sriastradh 			ATF_CHECK_MSG(aborted,
370*faf3bea1Sriastradh 			    "[%u] missing invariant assertion", i);
371*faf3bea1Sriastradh 			ATF_CHECK_MSG(jmp_sig == SIGABRT,
372*faf3bea1Sriastradh 			    "[%u] missing invariant assertion", i);
373*faf3bea1Sriastradh 		} else {
374*faf3bea1Sriastradh 			ATF_CHECK_MSG(!aborted, "[%u] raised signal %d: %s", i,
375*faf3bea1Sriastradh 			    jmp_sig, strsignal(jmp_sig));
376*faf3bea1Sriastradh 		}
377*faf3bea1Sriastradh 
378*faf3bea1Sriastradh 		ATF_CHECK_MSG((next.tv_sec == it.it_next.tv_sec &&
379*faf3bea1Sriastradh 			next.tv_nsec == it.it_next.tv_nsec),
380*faf3bea1Sriastradh 		    "[%u] periodic intervals of %lld.%09d from %lld.%09d"
381*faf3bea1Sriastradh 		    " last expired at %lld.%09d:"
382*faf3bea1Sriastradh 		    " next expiry at %lld.%09d, expected %lld.%09d", i,
383*faf3bea1Sriastradh 		    (long long)it.it_time.it_interval.tv_sec,
384*faf3bea1Sriastradh 		    (int)it.it_time.it_interval.tv_nsec,
385*faf3bea1Sriastradh 		    (long long)it.it_time.it_value.tv_sec,
386*faf3bea1Sriastradh 		    (int)it.it_time.it_value.tv_nsec,
387*faf3bea1Sriastradh 		    (long long)it.it_now.tv_sec, (int)it.it_now.tv_nsec,
388*faf3bea1Sriastradh 		    (long long)next.tv_sec, (int)next.tv_nsec,
389*faf3bea1Sriastradh 		    (long long)it.it_next.tv_sec, (int)it.it_next.tv_nsec);
390*faf3bea1Sriastradh 		ATF_CHECK_EQ_MSG(overruns, it.it_overruns,
391*faf3bea1Sriastradh 		    "[%u] periodic intervals of %lld.%09d from %lld.%09d"
392*faf3bea1Sriastradh 		    " last expired at %lld.%09d:"
393*faf3bea1Sriastradh 		    " overruns %d, expected %d", i,
394*faf3bea1Sriastradh 		    (long long)it.it_time.it_interval.tv_sec,
395*faf3bea1Sriastradh 		    (int)it.it_time.it_interval.tv_nsec,
396*faf3bea1Sriastradh 		    (long long)it.it_time.it_value.tv_sec,
397*faf3bea1Sriastradh 		    (int)it.it_time.it_value.tv_nsec,
398*faf3bea1Sriastradh 		    (long long)it.it_now.tv_sec, (int)it.it_now.tv_nsec,
399*faf3bea1Sriastradh 		    overruns, it.it_overruns);
400*faf3bea1Sriastradh 
401*faf3bea1Sriastradh 		if (it.it_xfail)
402*faf3bea1Sriastradh 			atf_tc_expect_pass();
403*faf3bea1Sriastradh 	}
404*faf3bea1Sriastradh }
405*faf3bea1Sriastradh 
406*faf3bea1Sriastradh ATF_TP_ADD_TCS(tp)
407*faf3bea1Sriastradh {
408*faf3bea1Sriastradh 
409*faf3bea1Sriastradh 	ATF_TP_ADD_TC(tp, itimer_transitions);
410*faf3bea1Sriastradh 
411*faf3bea1Sriastradh 	return atf_no_error();
412*faf3bea1Sriastradh }
413*faf3bea1Sriastradh 
414