1 1.3 riastrad /* $NetBSD: subr_time_arith.c,v 1.3 2025/04/01 23:14:23 riastradh Exp $ */ 2 1.1 riastrad 3 1.1 riastrad /*- 4 1.1 riastrad * Copyright (c) 2000, 2004, 2005, 2007, 2008, 2009, 2020 5 1.1 riastrad * The NetBSD Foundation, Inc. 6 1.1 riastrad * All rights reserved. 7 1.1 riastrad * 8 1.1 riastrad * This code is derived from software contributed to The NetBSD Foundation 9 1.1 riastrad * by Christopher G. Demetriou, by Andrew Doran, and by Jason R. Thorpe. 10 1.1 riastrad * 11 1.1 riastrad * Redistribution and use in source and binary forms, with or without 12 1.1 riastrad * modification, are permitted provided that the following conditions 13 1.1 riastrad * are met: 14 1.1 riastrad * 1. Redistributions of source code must retain the above copyright 15 1.1 riastrad * notice, this list of conditions and the following disclaimer. 16 1.1 riastrad * 2. Redistributions in binary form must reproduce the above copyright 17 1.1 riastrad * notice, this list of conditions and the following disclaimer in the 18 1.1 riastrad * documentation and/or other materials provided with the distribution. 19 1.1 riastrad * 20 1.1 riastrad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 1.1 riastrad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 1.1 riastrad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 1.1 riastrad * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 1.1 riastrad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 1.1 riastrad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 1.1 riastrad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 1.1 riastrad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 1.1 riastrad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 1.1 riastrad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 1.1 riastrad * POSSIBILITY OF SUCH DAMAGE. 31 1.1 riastrad */ 32 1.1 riastrad 33 1.1 riastrad /* 34 1.1 riastrad * Copyright (c) 1982, 1986, 1989, 1993 35 1.1 riastrad * The Regents of the University of California. All rights reserved. 36 1.1 riastrad * 37 1.1 riastrad * Redistribution and use in source and binary forms, with or without 38 1.1 riastrad * modification, are permitted provided that the following conditions 39 1.1 riastrad * are met: 40 1.1 riastrad * 1. Redistributions of source code must retain the above copyright 41 1.1 riastrad * notice, this list of conditions and the following disclaimer. 42 1.1 riastrad * 2. Redistributions in binary form must reproduce the above copyright 43 1.1 riastrad * notice, this list of conditions and the following disclaimer in the 44 1.1 riastrad * documentation and/or other materials provided with the distribution. 45 1.1 riastrad * 3. Neither the name of the University nor the names of its contributors 46 1.1 riastrad * may be used to endorse or promote products derived from this software 47 1.1 riastrad * without specific prior written permission. 48 1.1 riastrad * 49 1.1 riastrad * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 50 1.1 riastrad * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 51 1.1 riastrad * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 52 1.1 riastrad * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 53 1.1 riastrad * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 54 1.1 riastrad * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 55 1.1 riastrad * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 56 1.1 riastrad * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 57 1.1 riastrad * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 58 1.1 riastrad * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 59 1.1 riastrad * SUCH DAMAGE. 60 1.1 riastrad * 61 1.1 riastrad * @(#)kern_clock.c 8.5 (Berkeley) 1/21/94 62 1.1 riastrad * @(#)kern_time.c 8.4 (Berkeley) 5/26/95 63 1.1 riastrad */ 64 1.1 riastrad 65 1.1 riastrad #include <sys/cdefs.h> 66 1.3 riastrad __KERNEL_RCSID(0, "$NetBSD: subr_time_arith.c,v 1.3 2025/04/01 23:14:23 riastradh Exp $"); 67 1.1 riastrad 68 1.1 riastrad #include <sys/types.h> 69 1.1 riastrad 70 1.1 riastrad #include <sys/errno.h> 71 1.1 riastrad #include <sys/time.h> 72 1.1 riastrad #include <sys/timearith.h> 73 1.1 riastrad 74 1.1 riastrad #if defined(_KERNEL) 75 1.1 riastrad 76 1.1 riastrad #include <sys/kernel.h> 77 1.1 riastrad #include <sys/systm.h> 78 1.1 riastrad 79 1.1 riastrad #include <machine/limits.h> 80 1.1 riastrad 81 1.1 riastrad #elif defined(_TIME_TESTING) 82 1.1 riastrad 83 1.1 riastrad #include <assert.h> 84 1.1 riastrad #include <limits.h> 85 1.1 riastrad #include <stdbool.h> 86 1.1 riastrad 87 1.1 riastrad extern int hz; 88 1.2 riastrad extern int tick; 89 1.1 riastrad 90 1.1 riastrad #define KASSERT assert 91 1.3 riastrad #define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) 92 1.1 riastrad 93 1.1 riastrad #endif 94 1.1 riastrad 95 1.1 riastrad /* 96 1.1 riastrad * Compute number of ticks in the specified amount of time. 97 1.1 riastrad */ 98 1.1 riastrad int 99 1.1 riastrad tvtohz(const struct timeval *tv) 100 1.1 riastrad { 101 1.1 riastrad unsigned long ticks; 102 1.1 riastrad long sec, usec; 103 1.1 riastrad 104 1.1 riastrad /* 105 1.1 riastrad * If the number of usecs in the whole seconds part of the time 106 1.1 riastrad * difference fits in a long, then the total number of usecs will 107 1.1 riastrad * fit in an unsigned long. Compute the total and convert it to 108 1.1 riastrad * ticks, rounding up and adding 1 to allow for the current tick 109 1.1 riastrad * to expire. Rounding also depends on unsigned long arithmetic 110 1.1 riastrad * to avoid overflow. 111 1.1 riastrad * 112 1.1 riastrad * Otherwise, if the number of ticks in the whole seconds part of 113 1.1 riastrad * the time difference fits in a long, then convert the parts to 114 1.1 riastrad * ticks separately and add, using similar rounding methods and 115 1.1 riastrad * overflow avoidance. This method would work in the previous 116 1.1 riastrad * case, but it is slightly slower and assumes that hz is integral. 117 1.1 riastrad * 118 1.1 riastrad * Otherwise, round the time difference down to the maximum 119 1.1 riastrad * representable value. 120 1.1 riastrad * 121 1.1 riastrad * If ints are 32-bit, then the maximum value for any timeout in 122 1.1 riastrad * 10ms ticks is 248 days. 123 1.1 riastrad */ 124 1.1 riastrad sec = tv->tv_sec; 125 1.1 riastrad usec = tv->tv_usec; 126 1.1 riastrad 127 1.1 riastrad KASSERT(usec >= 0); 128 1.1 riastrad KASSERT(usec < 1000000); 129 1.1 riastrad 130 1.1 riastrad /* catch overflows in conversion time_t->int */ 131 1.1 riastrad if (tv->tv_sec > INT_MAX) 132 1.1 riastrad return INT_MAX; 133 1.1 riastrad if (tv->tv_sec < 0) 134 1.1 riastrad return 0; 135 1.1 riastrad 136 1.1 riastrad if (sec < 0 || (sec == 0 && usec == 0)) { 137 1.1 riastrad /* 138 1.1 riastrad * Would expire now or in the past. Return 0 ticks. 139 1.1 riastrad * This is different from the legacy tvhzto() interface, 140 1.1 riastrad * and callers need to check for it. 141 1.1 riastrad */ 142 1.1 riastrad ticks = 0; 143 1.1 riastrad } else if (sec <= (LONG_MAX / 1000000)) 144 1.1 riastrad ticks = (((sec * 1000000) + (unsigned long)usec + (tick - 1)) 145 1.1 riastrad / tick) + 1; 146 1.1 riastrad else if (sec <= (LONG_MAX / hz)) 147 1.1 riastrad ticks = (sec * hz) + 148 1.1 riastrad (((unsigned long)usec + (tick - 1)) / tick) + 1; 149 1.1 riastrad else 150 1.1 riastrad ticks = LONG_MAX; 151 1.1 riastrad 152 1.1 riastrad if (ticks > INT_MAX) 153 1.1 riastrad ticks = INT_MAX; 154 1.1 riastrad 155 1.1 riastrad return ((int)ticks); 156 1.1 riastrad } 157 1.1 riastrad 158 1.1 riastrad /* 159 1.1 riastrad * Check that a proposed value to load into the .it_value or 160 1.1 riastrad * .it_interval part of an interval timer is acceptable, and 161 1.1 riastrad * fix it to have at least minimal value (i.e. if it is less 162 1.1 riastrad * than the resolution of the clock, round it up.). We don't 163 1.1 riastrad * timeout the 0,0 value because this means to disable the 164 1.1 riastrad * timer or the interval. 165 1.1 riastrad */ 166 1.1 riastrad int 167 1.1 riastrad itimerfix(struct timeval *tv) 168 1.1 riastrad { 169 1.1 riastrad 170 1.1 riastrad if (tv->tv_usec < 0 || tv->tv_usec >= 1000000) 171 1.1 riastrad return EINVAL; 172 1.1 riastrad if (tv->tv_sec < 0) 173 1.1 riastrad return ETIMEDOUT; 174 1.1 riastrad if (tv->tv_sec == 0 && tv->tv_usec != 0 && tv->tv_usec < tick) 175 1.1 riastrad tv->tv_usec = tick; 176 1.1 riastrad return 0; 177 1.1 riastrad } 178 1.1 riastrad 179 1.1 riastrad int 180 1.1 riastrad itimespecfix(struct timespec *ts) 181 1.1 riastrad { 182 1.1 riastrad 183 1.1 riastrad if (ts->tv_nsec < 0 || ts->tv_nsec >= 1000000000) 184 1.1 riastrad return EINVAL; 185 1.1 riastrad if (ts->tv_sec < 0) 186 1.1 riastrad return ETIMEDOUT; 187 1.1 riastrad if (ts->tv_sec == 0 && ts->tv_nsec != 0 && ts->tv_nsec < tick * 1000) 188 1.1 riastrad ts->tv_nsec = tick * 1000; 189 1.1 riastrad return 0; 190 1.1 riastrad } 191 1.1 riastrad 192 1.1 riastrad /* 193 1.1 riastrad * timespecaddok(tsp, usp) 194 1.1 riastrad * 195 1.1 riastrad * True if tsp + usp can be computed without overflow, i.e., if it 196 1.1 riastrad * is OK to do timespecadd(tsp, usp, ...). 197 1.1 riastrad */ 198 1.1 riastrad bool 199 1.1 riastrad timespecaddok(const struct timespec *tsp, const struct timespec *usp) 200 1.1 riastrad { 201 1.1 riastrad enum { TIME_MIN = __type_min(time_t), TIME_MAX = __type_max(time_t) }; 202 1.1 riastrad time_t a = tsp->tv_sec; 203 1.1 riastrad time_t b = usp->tv_sec; 204 1.1 riastrad bool carry; 205 1.1 riastrad 206 1.1 riastrad /* 207 1.1 riastrad * Caller is responsible for guaranteeing valid timespec 208 1.1 riastrad * inputs. Any user-controlled inputs must be validated or 209 1.1 riastrad * adjusted. 210 1.1 riastrad */ 211 1.1 riastrad KASSERT(tsp->tv_nsec >= 0); 212 1.1 riastrad KASSERT(usp->tv_nsec >= 0); 213 1.1 riastrad KASSERT(tsp->tv_nsec < 1000000000L); 214 1.1 riastrad KASSERT(usp->tv_nsec < 1000000000L); 215 1.1 riastrad __CTASSERT(1000000000L <= __type_max(long) - 1000000000L); 216 1.1 riastrad 217 1.1 riastrad /* 218 1.1 riastrad * Fail if a + b + carry overflows TIME_MAX, or if a + b 219 1.1 riastrad * overflows TIME_MIN because timespecadd adds the carry after 220 1.1 riastrad * computing a + b. 221 1.1 riastrad * 222 1.1 riastrad * Break it into two mutually exclusive and exhaustive cases: 223 1.1 riastrad * I. a >= 0 224 1.1 riastrad * II. a < 0 225 1.1 riastrad */ 226 1.1 riastrad carry = (tsp->tv_nsec + usp->tv_nsec >= 1000000000L); 227 1.1 riastrad if (a >= 0) { 228 1.1 riastrad /* 229 1.1 riastrad * Case I: a >= 0. If b < 0, then b + 1 <= 0, so 230 1.1 riastrad * 231 1.1 riastrad * a + b + 1 <= a + 0 <= TIME_MAX, 232 1.1 riastrad * 233 1.1 riastrad * and 234 1.1 riastrad * 235 1.1 riastrad * a + b >= 0 + b = b >= TIME_MIN, 236 1.1 riastrad * 237 1.1 riastrad * so this can't overflow. 238 1.1 riastrad * 239 1.1 riastrad * If b >= 0, then a + b + carry >= a + b >= 0, so 240 1.1 riastrad * negative results and thus results below TIME_MIN are 241 1.1 riastrad * impossible; we need only avoid 242 1.1 riastrad * 243 1.1 riastrad * a + b + carry > TIME_MAX, 244 1.1 riastrad * 245 1.1 riastrad * which we will do by rejecting if 246 1.1 riastrad * 247 1.1 riastrad * b > TIME_MAX - a - carry, 248 1.1 riastrad * 249 1.1 riastrad * which in turn is incidentally always false if b < 0 250 1.1 riastrad * so we don't need extra logic to discriminate on the 251 1.1 riastrad * b >= 0 and b < 0 cases. 252 1.1 riastrad * 253 1.1 riastrad * Since 0 <= a <= TIME_MAX, we know 254 1.1 riastrad * 255 1.1 riastrad * 0 <= TIME_MAX - a <= TIME_MAX, 256 1.1 riastrad * 257 1.1 riastrad * and hence 258 1.1 riastrad * 259 1.1 riastrad * -1 <= TIME_MAX - a - 1 < TIME_MAX. 260 1.1 riastrad * 261 1.1 riastrad * So we can compute TIME_MAX - a - carry (i.e., either 262 1.1 riastrad * TIME_MAX - a or TIME_MAX - a - 1) safely without 263 1.1 riastrad * overflow. 264 1.1 riastrad */ 265 1.1 riastrad if (b > TIME_MAX - a - carry) 266 1.1 riastrad return false; 267 1.1 riastrad } else { 268 1.1 riastrad /* 269 1.1 riastrad * Case II: a < 0. If b >= 0, then since a + 1 <= 0, 270 1.1 riastrad * we have 271 1.1 riastrad * 272 1.1 riastrad * a + b + 1 <= b <= TIME_MAX, 273 1.1 riastrad * 274 1.1 riastrad * and 275 1.1 riastrad * 276 1.1 riastrad * a + b >= a >= TIME_MIN, 277 1.1 riastrad * 278 1.1 riastrad * so this can't overflow. 279 1.1 riastrad * 280 1.1 riastrad * If b < 0, then the intermediate a + b is negative 281 1.1 riastrad * and the outcome a + b + 1 is nonpositive, so we need 282 1.1 riastrad * only avoid 283 1.1 riastrad * 284 1.1 riastrad * a + b < TIME_MIN, 285 1.1 riastrad * 286 1.1 riastrad * which we will do by rejecting if 287 1.1 riastrad * 288 1.1 riastrad * a < TIME_MIN - b. 289 1.1 riastrad * 290 1.1 riastrad * (Reminder: The carry is added afterward in 291 1.1 riastrad * timespecadd, so to avoid overflow it is not enough 292 1.1 riastrad * to merely reject a + b + carry < TIME_MIN.) 293 1.1 riastrad * 294 1.1 riastrad * It is safe to compute the difference TIME_MIN - b 295 1.1 riastrad * because b is negative, so the result lies in 296 1.1 riastrad * (TIME_MIN, 0]. 297 1.1 riastrad */ 298 1.1 riastrad if (b < 0 && a < TIME_MIN - b) 299 1.1 riastrad return false; 300 1.1 riastrad } 301 1.1 riastrad 302 1.1 riastrad return true; 303 1.1 riastrad } 304 1.1 riastrad 305 1.1 riastrad /* 306 1.1 riastrad * timespecsubok(tsp, usp) 307 1.1 riastrad * 308 1.1 riastrad * True if tsp - usp can be computed without overflow, i.e., if it 309 1.1 riastrad * is OK to do timespecsub(tsp, usp, ...). 310 1.1 riastrad */ 311 1.1 riastrad bool 312 1.1 riastrad timespecsubok(const struct timespec *tsp, const struct timespec *usp) 313 1.1 riastrad { 314 1.1 riastrad enum { TIME_MIN = __type_min(time_t), TIME_MAX = __type_max(time_t) }; 315 1.1 riastrad time_t a = tsp->tv_sec, b = usp->tv_sec; 316 1.1 riastrad bool borrow; 317 1.1 riastrad 318 1.1 riastrad /* 319 1.1 riastrad * Caller is responsible for guaranteeing valid timespec 320 1.1 riastrad * inputs. Any user-controlled inputs must be validated or 321 1.1 riastrad * adjusted. 322 1.1 riastrad */ 323 1.1 riastrad KASSERT(tsp->tv_nsec >= 0); 324 1.1 riastrad KASSERT(usp->tv_nsec >= 0); 325 1.1 riastrad KASSERT(tsp->tv_nsec < 1000000000L); 326 1.1 riastrad KASSERT(usp->tv_nsec < 1000000000L); 327 1.1 riastrad __CTASSERT(1000000000L <= __type_max(long) - 1000000000L); 328 1.1 riastrad 329 1.1 riastrad /* 330 1.1 riastrad * Fail if a - b - borrow overflows TIME_MIN, or if a - b 331 1.1 riastrad * overflows TIME_MAX because timespecsub subtracts the borrow 332 1.1 riastrad * after computing a - b. 333 1.1 riastrad * 334 1.1 riastrad * Break it into two mutually exclusive and exhaustive cases: 335 1.1 riastrad * I. a < 0 336 1.1 riastrad * II. a >= 0 337 1.1 riastrad */ 338 1.1 riastrad borrow = (tsp->tv_nsec - usp->tv_nsec < 0); 339 1.1 riastrad if (a < 0) { 340 1.1 riastrad /* 341 1.1 riastrad * Case I: a < 0. If b < 0, then -b - 1 >= 0, so 342 1.1 riastrad * 343 1.1 riastrad * a - b - 1 >= a + 0 >= TIME_MIN, 344 1.1 riastrad * 345 1.1 riastrad * and, since a <= -1, provided that TIME_MIN <= 346 1.1 riastrad * -TIME_MAX - 1 so that TIME_MAX <= -TIME_MIN - 1 (in 347 1.1 riastrad * fact, equality holds, under the assumption of 348 1.1 riastrad * two's-complement arithmetic), 349 1.1 riastrad * 350 1.1 riastrad * a - b <= -1 - b = -b - 1 <= TIME_MAX, 351 1.1 riastrad * 352 1.1 riastrad * so this can't overflow. 353 1.1 riastrad */ 354 1.1 riastrad __CTASSERT(TIME_MIN <= -TIME_MAX - 1); 355 1.1 riastrad 356 1.1 riastrad /* 357 1.1 riastrad * If b >= 0, then a - b - borrow <= a - b < 0, so 358 1.1 riastrad * positive results and thus results above TIME_MAX are 359 1.1 riastrad * impossible; we need only avoid 360 1.1 riastrad * 361 1.1 riastrad * a - b - borrow < TIME_MIN, 362 1.1 riastrad * 363 1.1 riastrad * which we will do by rejecting if 364 1.1 riastrad * 365 1.1 riastrad * a < TIME_MIN + b + borrow. 366 1.1 riastrad * 367 1.1 riastrad * The right-hand side is safe to evaluate for any 368 1.1 riastrad * values of b and borrow as long as TIME_MIN + 369 1.1 riastrad * TIME_MAX + 1 <= TIME_MAX, i.e., TIME_MIN <= -1. 370 1.1 riastrad * (Note: If time_t were unsigned, this would fail!) 371 1.1 riastrad * 372 1.1 riastrad * Note: Unlike Case I in timespecaddok, this criterion 373 1.1 riastrad * does not work for b < 0, nor can the roles of a and 374 1.1 riastrad * b in the inequality be reversed (e.g., -b < TIME_MIN 375 1.1 riastrad * - a + borrow) without extra cases like checking for 376 1.1 riastrad * b = TEST_MIN. 377 1.1 riastrad */ 378 1.1 riastrad __CTASSERT(TIME_MIN < -1); 379 1.1 riastrad if (b >= 0 && a < TIME_MIN + b + borrow) 380 1.1 riastrad return false; 381 1.1 riastrad } else { 382 1.1 riastrad /* 383 1.1 riastrad * Case II: a >= 0. If b >= 0, then 384 1.1 riastrad * 385 1.1 riastrad * a - b <= a <= TIME_MAX, 386 1.1 riastrad * 387 1.1 riastrad * and, provided TIME_MIN <= -TIME_MAX - 1 (in fact, 388 1.1 riastrad * equality holds, under the assumption of 389 1.1 riastrad * two's-complement arithmetic) 390 1.1 riastrad * 391 1.1 riastrad * a - b - 1 >= -b - 1 >= -TIME_MAX - 1 >= TIME_MIN, 392 1.1 riastrad * 393 1.1 riastrad * so this can't overflow. 394 1.1 riastrad */ 395 1.1 riastrad __CTASSERT(TIME_MIN <= -TIME_MAX - 1); 396 1.1 riastrad 397 1.1 riastrad /* 398 1.1 riastrad * If b < 0, then a - b >= a >= 0, so negative results 399 1.1 riastrad * and thus results below TIME_MIN are impossible; we 400 1.1 riastrad * need only avoid 401 1.1 riastrad * 402 1.1 riastrad * a - b > TIME_MAX, 403 1.1 riastrad * 404 1.1 riastrad * which we will do by rejecting if 405 1.1 riastrad * 406 1.1 riastrad * a > TIME_MAX + b. 407 1.1 riastrad * 408 1.1 riastrad * (Reminder: The borrow is subtracted afterward in 409 1.1 riastrad * timespecsub, so to avoid overflow it is not enough 410 1.1 riastrad * to merely reject a - b - borrow > TIME_MAX.) 411 1.1 riastrad * 412 1.1 riastrad * It is safe to compute the sum TIME_MAX + b because b 413 1.1 riastrad * is negative, so the result lies in [0, TIME_MAX). 414 1.1 riastrad */ 415 1.1 riastrad if (b < 0 && a > TIME_MAX + b) 416 1.1 riastrad return false; 417 1.1 riastrad } 418 1.1 riastrad 419 1.1 riastrad return true; 420 1.1 riastrad } 421 1.1 riastrad 422 1.3 riastrad static bool 423 1.3 riastrad timespec2nsok(const struct timespec *ts) 424 1.3 riastrad { 425 1.3 riastrad 426 1.3 riastrad return ts->tv_sec < INT64_MAX/1000000000 || 427 1.3 riastrad (ts->tv_sec == INT64_MAX/1000000000 && 428 1.3 riastrad ts->tv_nsec <= INT64_MAX - (INT64_MAX/1000000000)*1000000000); 429 1.3 riastrad } 430 1.3 riastrad 431 1.1 riastrad /* 432 1.1 riastrad * itimer_transition(it, now, next, &overruns) 433 1.1 riastrad * 434 1.1 riastrad * Given: 435 1.1 riastrad * 436 1.1 riastrad * - it: the current state of an itimer (it_value = last expiry 437 1.1 riastrad * time, it_interval = periodic rescheduling interval), and 438 1.1 riastrad * 439 1.1 riastrad * - now: the current time on the itimer's clock; 440 1.1 riastrad * 441 1.1 riastrad * compute: 442 1.1 riastrad * 443 1.1 riastrad * - next: the next time the itimer should be scheduled for, and 444 1.1 riastrad * - overruns: the number of overruns if we're firing late. 445 1.1 riastrad * 446 1.1 riastrad * XXX This should maybe also say whether the itimer should expire 447 1.1 riastrad * at all. 448 1.1 riastrad */ 449 1.1 riastrad void 450 1.1 riastrad itimer_transition(const struct itimerspec *restrict it, 451 1.1 riastrad const struct timespec *restrict now, 452 1.1 riastrad struct timespec *restrict next, 453 1.1 riastrad int *restrict overrunsp) 454 1.1 riastrad { 455 1.3 riastrad int64_t last_val, next_val, interval, remainder, now_ns; 456 1.1 riastrad int backwards; 457 1.1 riastrad 458 1.1 riastrad /* 459 1.1 riastrad * Zero the outputs so we can test assertions in userland 460 1.1 riastrad * without undefined behaviour. 461 1.1 riastrad */ 462 1.1 riastrad timespecclear(next); 463 1.1 riastrad *overrunsp = 0; 464 1.1 riastrad 465 1.1 riastrad /* 466 1.1 riastrad * Paranoia: Caller should guarantee this. 467 1.1 riastrad */ 468 1.1 riastrad if (!timespecisset(&it->it_interval)) { 469 1.1 riastrad timespecclear(next); 470 1.1 riastrad return; 471 1.1 riastrad } 472 1.1 riastrad 473 1.3 riastrad /* Did the clock wind backwards? */ 474 1.1 riastrad backwards = (timespeccmp(&it->it_value, now, >)); 475 1.1 riastrad 476 1.3 riastrad /* Valid value and interval guaranteed by itimerfix. */ 477 1.3 riastrad KASSERT(it->it_value.tv_sec >= 0); 478 1.3 riastrad KASSERT(it->it_value.tv_nsec < 1000000000); 479 1.3 riastrad KASSERT(it->it_interval.tv_sec >= 0); 480 1.3 riastrad KASSERT(it->it_interval.tv_nsec < 1000000000); 481 1.3 riastrad 482 1.1 riastrad /* Nonnegative interval guaranteed by itimerfix. */ 483 1.1 riastrad KASSERT(it->it_interval.tv_sec >= 0); 484 1.1 riastrad KASSERT(it->it_interval.tv_nsec >= 0); 485 1.1 riastrad 486 1.1 riastrad /* Handle the easy case of non-overflown timers first. */ 487 1.3 riastrad if (__predict_true(!backwards)) { 488 1.3 riastrad if (__predict_false(!timespecaddok(&it->it_value, 489 1.3 riastrad &it->it_interval))) 490 1.3 riastrad goto overflow; 491 1.3 riastrad timespecadd(&it->it_value, &it->it_interval, next); 492 1.3 riastrad if (__predict_true(timespeccmp(now, next, <))) 493 1.3 riastrad return; 494 1.3 riastrad } 495 1.1 riastrad 496 1.3 riastrad /* 497 1.3 riastrad * If we can't represent the input as a number of nanoseconds, 498 1.3 riastrad * bail. This is good up to the year 2262, if we start 499 1.3 riastrad * counting from 1970 (2^63 nanoseconds ~ 292 years). 500 1.3 riastrad */ 501 1.3 riastrad if (__predict_false(!timespec2nsok(now)) || 502 1.3 riastrad __predict_false(!timespec2nsok(&it->it_value)) || 503 1.3 riastrad __predict_false(!timespec2nsok(&it->it_interval))) 504 1.3 riastrad goto overflow; 505 1.3 riastrad 506 1.3 riastrad now_ns = timespec2ns(now); 507 1.3 riastrad last_val = timespec2ns(&it->it_value); 508 1.3 riastrad interval = timespec2ns(&it->it_interval); 509 1.3 riastrad 510 1.3 riastrad KASSERT(now_ns >= 0); 511 1.3 riastrad KASSERT(last_val >= 0); 512 1.3 riastrad KASSERT(interval >= 0); 513 1.1 riastrad 514 1.3 riastrad /* 515 1.3 riastrad * now [backwards] overruns now [forwards] 516 1.3 riastrad * | v v v | 517 1.3 riastrad * |--+----+-*--x----+----+----|----+----+----+--*-x----+--> 518 1.3 riastrad * \/ | \/ 519 1.3 riastrad * remainder last_val remainder 520 1.3 riastrad * (zero or negative) (zero or positive) 521 1.3 riastrad * 522 1.3 riastrad * Set next_val to last_value + k*interval for some k. 523 1.3 riastrad * 524 1.3 riastrad * The interval is always positive, and division in C 525 1.3 riastrad * truncates, so dividing a positive duration by the interval 526 1.3 riastrad * always gives zero or a positive remainder, and dividing a 527 1.3 riastrad * negative duration by the interval always gives zero or a 528 1.3 riastrad * negative remainder. Hence: 529 1.3 riastrad * 530 1.3 riastrad * - If now_ns < last_val -- which happens iff backwards, i.e., 531 1.3 riastrad * the clock was wound backwards -- then remainder is zero or 532 1.3 riastrad * negative, so subtracting it stays in place or moves 533 1.3 riastrad * forward in time, and thus this finds the _earliest_ value 534 1.3 riastrad * that is not earlier than now_ns. We will advance this by 535 1.3 riastrad * one more interval if we are already firing exactly on the 536 1.3 riastrad * interval to find the earliest value _after_ now_ns. 537 1.3 riastrad * 538 1.3 riastrad * - If now_ns > last_val -- which happens iff !backwards, 539 1.3 riastrad * i.e., the clock ran fast -- then remainder is zero or 540 1.3 riastrad * positive positive, so this finds the _latest_ value not 541 1.3 riastrad * later than now_ns. We will always advance this by one 542 1.3 riastrad * more interval to find the earliest value _after_ now_ns. 543 1.3 riastrad * We will also count overflows. 544 1.3 riastrad * 545 1.3 riastrad * (now_ns == last_val is not possible at this point because it 546 1.3 riastrad * only happens if the addition of struct timespec would 547 1.3 riastrad * overflow, and that is only possible when timespec2ns would 548 1.3 riastrad * also overflow for at least one of the inputs.) 549 1.3 riastrad */ 550 1.3 riastrad KASSERT(last_val != now_ns); 551 1.3 riastrad remainder = (now_ns - last_val) % interval; 552 1.3 riastrad next_val = now_ns - remainder; 553 1.3 riastrad KASSERT((last_val - next_val) % interval == 0); 554 1.3 riastrad if (backwards) { 555 1.3 riastrad /* 556 1.3 riastrad * If the clock was wound back to an exact multiple of 557 1.3 riastrad * the interval, so next_val = now_ns, don't demand to 558 1.3 riastrad * fire again in the same instant -- advance to the 559 1.3 riastrad * next interval. Overflow is not possible; proof is 560 1.3 riastrad * asserted. 561 1.3 riastrad */ 562 1.3 riastrad if (remainder == 0) { 563 1.3 riastrad KASSERT(now_ns < last_val); 564 1.3 riastrad KASSERT(next_val == now_ns); 565 1.3 riastrad KASSERT(last_val - next_val >= interval); 566 1.3 riastrad KASSERT(interval <= last_val - next_val); 567 1.3 riastrad KASSERT(next_val <= last_val - interval); 568 1.3 riastrad KASSERT(next_val <= INT64_MAX - interval); 569 1.1 riastrad next_val += interval; 570 1.3 riastrad } 571 1.3 riastrad } else { 572 1.3 riastrad /* 573 1.3 riastrad * next_val is the largest integer multiple of interval 574 1.3 riastrad * not later than now_ns. Count the number of full 575 1.3 riastrad * intervals that were skipped (division should be 576 1.3 riastrad * exact here), not counting any partial interval 577 1.3 riastrad * between next_val and now_ns, as the number of 578 1.3 riastrad * overruns. Advance by one interval -- unless that 579 1.3 riastrad * would overflow. 580 1.3 riastrad */ 581 1.3 riastrad *overrunsp += MIN(INT_MAX - *overrunsp, 582 1.3 riastrad (next_val - last_val) / interval); 583 1.3 riastrad if (__predict_false(next_val > INT64_MAX - interval)) 584 1.3 riastrad goto overflow; 585 1.3 riastrad next_val += interval; 586 1.3 riastrad } 587 1.1 riastrad 588 1.3 riastrad next->tv_sec = next_val / 1000000000; 589 1.3 riastrad next->tv_nsec = next_val % 1000000000; 590 1.3 riastrad return; 591 1.3 riastrad 592 1.3 riastrad overflow: 593 1.3 riastrad next->tv_sec = 0; 594 1.3 riastrad next->tv_nsec = 0; 595 1.1 riastrad } 596