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