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 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); 390 ATF_TC_HEAD(itimer_transitions, tc) 391 { 392 atf_tc_set_md_var(tc, "descr", 393 "Tests interval timer transitions"); 394 } 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 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