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