1 /* $OpenBSD: kern_time.c,v 1.66 2009/06/05 15:17:02 ckuethe Exp $ */ 2 /* $NetBSD: kern_time.c,v 1.20 1996/02/18 11:57:06 fvdl Exp $ */ 3 4 /* 5 * Copyright (c) 1982, 1986, 1989, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 * @(#)kern_time.c 8.4 (Berkeley) 5/26/95 33 */ 34 35 #include <sys/param.h> 36 #include <sys/resourcevar.h> 37 #include <sys/kernel.h> 38 #include <sys/systm.h> 39 #include <sys/proc.h> 40 #include <sys/vnode.h> 41 #include <sys/signalvar.h> 42 #ifdef __HAVE_TIMECOUNTER 43 #include <sys/timetc.h> 44 #endif 45 46 #include <sys/mount.h> 47 #include <sys/syscallargs.h> 48 49 #include <machine/cpu.h> 50 51 void itimerround(struct timeval *); 52 53 /* 54 * Time of day and interval timer support. 55 * 56 * These routines provide the kernel entry points to get and set 57 * the time-of-day and per-process interval timers. Subroutines 58 * here provide support for adding and subtracting timeval structures 59 * and decrementing interval timers, optionally reloading the interval 60 * timers when they expire. 61 */ 62 63 /* This function is used by clock_settime and settimeofday */ 64 #ifdef __HAVE_TIMECOUNTER 65 int 66 settime(struct timespec *ts) 67 { 68 struct timespec now; 69 70 71 /* 72 * Don't allow the time to be set forward so far it will wrap 73 * and become negative, thus allowing an attacker to bypass 74 * the next check below. The cutoff is 1 year before rollover 75 * occurs, so even if the attacker uses adjtime(2) to move 76 * the time past the cutoff, it will take a very long time 77 * to get to the wrap point. 78 * 79 * XXX: we check against INT_MAX since on 64-bit 80 * platforms, sizeof(int) != sizeof(long) and 81 * time_t is 32 bits even when atv.tv_sec is 64 bits. 82 */ 83 if (ts->tv_sec > INT_MAX - 365*24*60*60) { 84 printf("denied attempt to set clock forward to %ld\n", 85 ts->tv_sec); 86 return (EPERM); 87 } 88 /* 89 * If the system is secure, we do not allow the time to be 90 * set to an earlier value (it may be slowed using adjtime, 91 * but not set back). This feature prevent interlopers from 92 * setting arbitrary time stamps on files. 93 */ 94 nanotime(&now); 95 if (securelevel > 1 && timespeccmp(ts, &now, <)) { 96 printf("denied attempt to set clock back %ld seconds\n", 97 now.tv_sec - ts->tv_sec); 98 return (EPERM); 99 } 100 101 tc_setclock(ts); 102 resettodr(); 103 104 return (0); 105 } 106 #else 107 int 108 settime(struct timespec *ts) 109 { 110 struct timeval delta, tvv, *tv; 111 int s; 112 113 /* XXX - Ugh. */ 114 tv = &tvv; 115 tvv.tv_sec = ts->tv_sec; 116 tvv.tv_usec = ts->tv_nsec / 1000; 117 118 /* 119 * Don't allow the time to be set forward so far it will wrap 120 * and become negative, thus allowing an attacker to bypass 121 * the next check below. The cutoff is 1 year before rollover 122 * occurs, so even if the attacker uses adjtime(2) to move 123 * the time past the cutoff, it will take a very long time 124 * to get to the wrap point. 125 * 126 * XXX: we check against INT_MAX since on 64-bit 127 * platforms, sizeof(int) != sizeof(long) and 128 * time_t is 32 bits even when atv.tv_sec is 64 bits. 129 */ 130 if (tv->tv_sec > INT_MAX - 365*24*60*60) { 131 printf("denied attempt to set clock forward to %ld\n", 132 tv->tv_sec); 133 return (EPERM); 134 } 135 /* 136 * If the system is secure, we do not allow the time to be 137 * set to an earlier value (it may be slowed using adjtime, 138 * but not set back). This feature prevent interlopers from 139 * setting arbitrary time stamps on files. 140 */ 141 if (securelevel > 1 && timercmp(tv, &time, <)) { 142 printf("denied attempt to set clock back %ld seconds\n", 143 time_second - tv->tv_sec); 144 return (EPERM); 145 } 146 147 /* WHAT DO WE DO ABOUT PENDING REAL-TIME TIMEOUTS??? */ 148 s = splclock(); 149 timersub(tv, &time, &delta); 150 time = *tv; 151 timeradd(&boottime, &delta, &boottime); 152 splx(s); 153 resettodr(); 154 155 return (0); 156 } 157 #endif 158 159 /* ARGSUSED */ 160 int 161 sys_clock_gettime(struct proc *p, void *v, register_t *retval) 162 { 163 struct sys_clock_gettime_args /* { 164 syscallarg(clockid_t) clock_id; 165 syscallarg(struct timespec *) tp; 166 } */ *uap = v; 167 clockid_t clock_id; 168 struct timespec ats; 169 170 clock_id = SCARG(uap, clock_id); 171 switch (clock_id) { 172 case CLOCK_REALTIME: 173 nanotime(&ats); 174 break; 175 case CLOCK_MONOTONIC: 176 nanouptime(&ats); 177 break; 178 case CLOCK_PROF: 179 ats.tv_sec = p->p_rtime.tv_sec; 180 ats.tv_nsec = p->p_rtime.tv_usec * 1000; 181 break; 182 default: 183 return (EINVAL); 184 } 185 186 return copyout(&ats, SCARG(uap, tp), sizeof(ats)); 187 } 188 189 /* ARGSUSED */ 190 int 191 sys_clock_settime(struct proc *p, void *v, register_t *retval) 192 { 193 struct sys_clock_settime_args /* { 194 syscallarg(clockid_t) clock_id; 195 syscallarg(const struct timespec *) tp; 196 } */ *uap = v; 197 struct timespec ats; 198 clockid_t clock_id; 199 int error; 200 201 if ((error = suser(p, 0)) != 0) 202 return (error); 203 204 if ((error = copyin(SCARG(uap, tp), &ats, sizeof(ats))) != 0) 205 return (error); 206 207 clock_id = SCARG(uap, clock_id); 208 switch (clock_id) { 209 case CLOCK_REALTIME: 210 if ((error = settime(&ats)) != 0) 211 return (error); 212 break; 213 default: /* Other clocks are read-only */ 214 return (EINVAL); 215 } 216 217 return (0); 218 } 219 220 int 221 sys_clock_getres(struct proc *p, void *v, register_t *retval) 222 { 223 struct sys_clock_getres_args /* { 224 syscallarg(clockid_t) clock_id; 225 syscallarg(struct timespec *) tp; 226 } */ *uap = v; 227 clockid_t clock_id; 228 struct timespec ts; 229 int error = 0; 230 231 clock_id = SCARG(uap, clock_id); 232 switch (clock_id) { 233 case CLOCK_REALTIME: 234 case CLOCK_MONOTONIC: 235 ts.tv_sec = 0; 236 ts.tv_nsec = 1000000000 / hz; 237 break; 238 default: 239 return (EINVAL); 240 } 241 242 if (SCARG(uap, tp)) 243 error = copyout(&ts, SCARG(uap, tp), sizeof (ts)); 244 245 return error; 246 } 247 248 /* ARGSUSED */ 249 int 250 sys_nanosleep(struct proc *p, void *v, register_t *retval) 251 { 252 static int nanowait; 253 struct sys_nanosleep_args/* { 254 syscallarg(const struct timespec *) rqtp; 255 syscallarg(struct timespec *) rmtp; 256 } */ *uap = v; 257 struct timespec rqt, rmt; 258 struct timespec sts, ets; 259 struct timeval tv; 260 int error, error1; 261 262 error = copyin((const void *)SCARG(uap, rqtp), (void *)&rqt, 263 sizeof(struct timespec)); 264 if (error) 265 return (error); 266 267 TIMESPEC_TO_TIMEVAL(&tv, &rqt); 268 if (itimerfix(&tv)) 269 return (EINVAL); 270 271 if (SCARG(uap, rmtp)) 272 getnanouptime(&sts); 273 274 error = tsleep(&nanowait, PWAIT | PCATCH, "nanosleep", 275 MAX(1, tvtohz(&tv))); 276 if (error == ERESTART) 277 error = EINTR; 278 if (error == EWOULDBLOCK) 279 error = 0; 280 281 if (SCARG(uap, rmtp)) { 282 getnanouptime(&ets); 283 284 timespecsub(&ets, &sts, &sts); 285 timespecsub(&rqt, &sts, &rmt); 286 287 if (rmt.tv_sec < 0) 288 timespecclear(&rmt); 289 290 error1 = copyout((void *)&rmt, (void *)SCARG(uap,rmtp), 291 sizeof(rmt)); 292 if (error1 != 0) 293 error = error1; 294 } 295 296 return error; 297 } 298 299 /* ARGSUSED */ 300 int 301 sys_gettimeofday(struct proc *p, void *v, register_t *retval) 302 { 303 struct sys_gettimeofday_args /* { 304 syscallarg(struct timeval *) tp; 305 syscallarg(struct timezone *) tzp; 306 } */ *uap = v; 307 struct timeval atv; 308 int error = 0; 309 310 if (SCARG(uap, tp)) { 311 microtime(&atv); 312 if ((error = copyout((void *)&atv, (void *)SCARG(uap, tp), 313 sizeof (atv)))) 314 return (error); 315 } 316 if (SCARG(uap, tzp)) 317 error = copyout((void *)&tz, (void *)SCARG(uap, tzp), 318 sizeof (tz)); 319 return (error); 320 } 321 322 #ifdef __HAVE_TIMECOUNTER 323 struct timeval adjtimedelta; /* unapplied time correction */ 324 #else 325 int tickdelta; /* current clock skew, us. per tick */ 326 long timedelta; /* unapplied time correction, us. */ 327 long bigadj = 1000000; /* use 10x skew above bigadj us. */ 328 int64_t ntp_tick_permanent; 329 int64_t ntp_tick_acc; 330 #endif 331 332 /* ARGSUSED */ 333 int 334 sys_settimeofday(struct proc *p, void *v, register_t *retval) 335 { 336 struct sys_settimeofday_args /* { 337 syscallarg(const struct timeval *) tv; 338 syscallarg(const struct timezone *) tzp; 339 } */ *uap = v; 340 struct timezone atz; 341 struct timeval atv; 342 int error; 343 344 if ((error = suser(p, 0))) 345 return (error); 346 /* Verify all parameters before changing time. */ 347 if (SCARG(uap, tv) && (error = copyin((void *)SCARG(uap, tv), 348 (void *)&atv, sizeof(atv)))) 349 return (error); 350 if (SCARG(uap, tzp) && (error = copyin((void *)SCARG(uap, tzp), 351 (void *)&atz, sizeof(atz)))) 352 return (error); 353 if (SCARG(uap, tv)) { 354 struct timespec ts; 355 356 /* 357 * Adjtime in progress is meaningless or harmful after 358 * setting the clock. Cancel adjtime and then set new time. 359 */ 360 #ifdef __HAVE_TIMECOUNTER 361 adjtimedelta.tv_usec = 0; 362 adjtimedelta.tv_sec = 0; 363 #else 364 int s = splclock(); 365 tickdelta = 0; 366 timedelta = 0; 367 splx(s); 368 #endif 369 370 TIMEVAL_TO_TIMESPEC(&atv, &ts); 371 if ((error = settime(&ts)) != 0) 372 return (error); 373 } 374 if (SCARG(uap, tzp)) 375 tz = atz; 376 return (0); 377 } 378 379 /* ARGSUSED */ 380 int 381 sys_adjfreq(struct proc *p, void *v, register_t *retval) 382 { 383 struct sys_adjfreq_args /* { 384 syscallarg(const int64_t *) freq; 385 syscallarg(int64_t *) oldfreq; 386 } */ *uap = v; 387 int error; 388 int64_t f; 389 #ifndef __HAVE_TIMECOUNTER 390 int s; 391 392 if (SCARG(uap, oldfreq)) { 393 f = ntp_tick_permanent * hz; 394 if ((error = copyout((void *)&f, (void *)SCARG(uap, oldfreq), 395 sizeof(int64_t)))) 396 return (error); 397 } 398 if (SCARG(uap, freq)) { 399 if ((error = suser(p, 0))) 400 return (error); 401 if ((error = copyin((void *)SCARG(uap, freq), (void *)&f, 402 sizeof(int64_t)))) 403 return (error); 404 s = splclock(); 405 ntp_tick_permanent = f / hz; 406 splx(s); 407 } 408 #else 409 if (SCARG(uap, oldfreq)) { 410 if ((error = tc_adjfreq(&f, NULL)) != 0) 411 return (error); 412 if ((error = copyout(&f, SCARG(uap, oldfreq), sizeof(f))) != 0) 413 return (error); 414 } 415 if (SCARG(uap, freq)) { 416 if ((error = suser(p, 0))) 417 return (error); 418 if ((error = copyin(SCARG(uap, freq), &f, sizeof(f))) != 0) 419 return (error); 420 if ((error = tc_adjfreq(NULL, &f)) != 0) 421 return (error); 422 } 423 #endif 424 return (0); 425 } 426 427 /* ARGSUSED */ 428 int 429 sys_adjtime(struct proc *p, void *v, register_t *retval) 430 { 431 struct sys_adjtime_args /* { 432 syscallarg(const struct timeval *) delta; 433 syscallarg(struct timeval *) olddelta; 434 } */ *uap = v; 435 #ifdef __HAVE_TIMECOUNTER 436 int error; 437 438 if (SCARG(uap, olddelta)) 439 if ((error = copyout((void *)&adjtimedelta, 440 (void *)SCARG(uap, olddelta), sizeof(struct timeval)))) 441 return (error); 442 443 if (SCARG(uap, delta)) { 444 if ((error = suser(p, 0))) 445 return (error); 446 447 if ((error = copyin((void *)SCARG(uap, delta), 448 (void *)&adjtimedelta, sizeof(struct timeval)))) 449 return (error); 450 } 451 452 /* Normalize the correction. */ 453 while (adjtimedelta.tv_usec >= 1000000) { 454 adjtimedelta.tv_usec -= 1000000; 455 adjtimedelta.tv_sec += 1; 456 } 457 while (adjtimedelta.tv_usec < 0) { 458 adjtimedelta.tv_usec += 1000000; 459 adjtimedelta.tv_sec -= 1; 460 } 461 return (0); 462 #else 463 struct timeval atv; 464 long ndelta, ntickdelta, odelta; 465 int s, error; 466 467 if (!SCARG(uap, delta)) { 468 s = splclock(); 469 odelta = timedelta; 470 splx(s); 471 goto out; 472 } 473 if ((error = suser(p, 0))) 474 return (error); 475 if ((error = copyin((void *)SCARG(uap, delta), (void *)&atv, 476 sizeof(struct timeval)))) 477 return (error); 478 479 /* 480 * Compute the total correction and the rate at which to apply it. 481 * Round the adjustment down to a whole multiple of the per-tick 482 * delta, so that after some number of incremental changes in 483 * hardclock(), tickdelta will become zero, lest the correction 484 * overshoot and start taking us away from the desired final time. 485 */ 486 if (atv.tv_sec > LONG_MAX / 1000000L) 487 ndelta = LONG_MAX; 488 else if (atv.tv_sec < LONG_MIN / 1000000L) 489 ndelta = LONG_MIN; 490 else { 491 ndelta = atv.tv_sec * 1000000L; 492 odelta = ndelta; 493 ndelta += atv.tv_usec; 494 if (atv.tv_usec > 0 && ndelta <= odelta) 495 ndelta = LONG_MAX; 496 else if (atv.tv_usec < 0 && ndelta >= odelta) 497 ndelta = LONG_MIN; 498 } 499 500 if (ndelta > bigadj || ndelta < -bigadj) 501 ntickdelta = 10 * tickadj; 502 else 503 ntickdelta = tickadj; 504 if (ndelta % ntickdelta) 505 ndelta = ndelta / ntickdelta * ntickdelta; 506 507 /* 508 * To make hardclock()'s job easier, make the per-tick delta negative 509 * if we want time to run slower; then hardclock can simply compute 510 * tick + tickdelta, and subtract tickdelta from timedelta. 511 */ 512 if (ndelta < 0) 513 ntickdelta = -ntickdelta; 514 s = splclock(); 515 odelta = timedelta; 516 timedelta = ndelta; 517 tickdelta = ntickdelta; 518 splx(s); 519 520 out: 521 if (SCARG(uap, olddelta)) { 522 atv.tv_sec = odelta / 1000000; 523 atv.tv_usec = odelta % 1000000; 524 if ((error = copyout((void *)&atv, (void *)SCARG(uap, olddelta), 525 sizeof(struct timeval)))) 526 return (error); 527 } 528 return (0); 529 #endif 530 } 531 532 533 /* 534 * Get value of an interval timer. The process virtual and 535 * profiling virtual time timers are kept in the p_stats area, since 536 * they can be swapped out. These are kept internally in the 537 * way they are specified externally: in time until they expire. 538 * 539 * The real time interval timer is kept in the process table slot 540 * for the process, and its value (it_value) is kept as an 541 * absolute time rather than as a delta, so that it is easy to keep 542 * periodic real-time signals from drifting. 543 * 544 * Virtual time timers are processed in the hardclock() routine of 545 * kern_clock.c. The real time timer is processed by a timeout 546 * routine, called from the softclock() routine. Since a callout 547 * may be delayed in real time due to interrupt processing in the system, 548 * it is possible for the real time timeout routine (realitexpire, given below), 549 * to be delayed in real time past when it is supposed to occur. It 550 * does not suffice, therefore, to reload the real timer .it_value from the 551 * real time timers .it_interval. Rather, we compute the next time in 552 * absolute time the timer should go off. 553 */ 554 /* ARGSUSED */ 555 int 556 sys_getitimer(struct proc *p, void *v, register_t *retval) 557 { 558 struct sys_getitimer_args /* { 559 syscallarg(int) which; 560 syscallarg(struct itimerval *) itv; 561 } */ *uap = v; 562 struct itimerval aitv; 563 int s; 564 565 if (SCARG(uap, which) < ITIMER_REAL || SCARG(uap, which) > ITIMER_PROF) 566 return (EINVAL); 567 s = splclock(); 568 if (SCARG(uap, which) == ITIMER_REAL) { 569 struct timeval now; 570 571 getmicrouptime(&now); 572 /* 573 * Convert from absolute to relative time in .it_value 574 * part of real time timer. If time for real time timer 575 * has passed return 0, else return difference between 576 * current time and time for the timer to go off. 577 */ 578 aitv = p->p_realtimer; 579 if (timerisset(&aitv.it_value)) { 580 if (timercmp(&aitv.it_value, &now, <)) 581 timerclear(&aitv.it_value); 582 else 583 timersub(&aitv.it_value, &now, 584 &aitv.it_value); 585 } 586 } else 587 aitv = p->p_stats->p_timer[SCARG(uap, which)]; 588 splx(s); 589 return (copyout((void *)&aitv, (void *)SCARG(uap, itv), 590 sizeof (struct itimerval))); 591 } 592 593 /* ARGSUSED */ 594 int 595 sys_setitimer(struct proc *p, void *v, register_t *retval) 596 { 597 struct sys_setitimer_args /* { 598 syscallarg(int) which; 599 syscallarg(const struct itimerval *) itv; 600 syscallarg(struct itimerval *) oitv; 601 } */ *uap = v; 602 struct sys_getitimer_args getargs; 603 struct itimerval aitv; 604 const struct itimerval *itvp; 605 int error; 606 int timo; 607 608 if (SCARG(uap, which) < ITIMER_REAL || SCARG(uap, which) > ITIMER_PROF) 609 return (EINVAL); 610 itvp = SCARG(uap, itv); 611 if (itvp && (error = copyin((void *)itvp, (void *)&aitv, 612 sizeof(struct itimerval)))) 613 return (error); 614 if (SCARG(uap, oitv) != NULL) { 615 SCARG(&getargs, which) = SCARG(uap, which); 616 SCARG(&getargs, itv) = SCARG(uap, oitv); 617 if ((error = sys_getitimer(p, &getargs, retval))) 618 return (error); 619 } 620 if (itvp == 0) 621 return (0); 622 if (itimerfix(&aitv.it_value) || itimerfix(&aitv.it_interval)) 623 return (EINVAL); 624 if (SCARG(uap, which) == ITIMER_REAL) { 625 struct timeval ctv; 626 627 timeout_del(&p->p_realit_to); 628 getmicrouptime(&ctv); 629 if (timerisset(&aitv.it_value)) { 630 timo = tvtohz(&aitv.it_value); 631 timeout_add(&p->p_realit_to, timo); 632 timeradd(&aitv.it_value, &ctv, &aitv.it_value); 633 } 634 p->p_realtimer = aitv; 635 } else { 636 int s; 637 638 itimerround(&aitv.it_interval); 639 s = splclock(); 640 p->p_stats->p_timer[SCARG(uap, which)] = aitv; 641 splx(s); 642 } 643 644 return (0); 645 } 646 647 /* 648 * Real interval timer expired: 649 * send process whose timer expired an alarm signal. 650 * If time is not set up to reload, then just return. 651 * Else compute next time timer should go off which is > current time. 652 * This is where delay in processing this timeout causes multiple 653 * SIGALRM calls to be compressed into one. 654 */ 655 void 656 realitexpire(void *arg) 657 { 658 struct proc *p; 659 660 p = (struct proc *)arg; 661 psignal(p, SIGALRM); 662 if (!timerisset(&p->p_realtimer.it_interval)) { 663 timerclear(&p->p_realtimer.it_value); 664 return; 665 } 666 for (;;) { 667 struct timeval ctv, ntv; 668 int timo; 669 670 timeradd(&p->p_realtimer.it_value, 671 &p->p_realtimer.it_interval, &p->p_realtimer.it_value); 672 getmicrouptime(&ctv); 673 if (timercmp(&p->p_realtimer.it_value, &ctv, >)) { 674 ntv = p->p_realtimer.it_value; 675 timersub(&ntv, &ctv, &ntv); 676 timo = tvtohz(&ntv) - 1; 677 if (timo <= 0) 678 timo = 1; 679 if ((p->p_flag & P_WEXIT) == 0) 680 timeout_add(&p->p_realit_to, timo); 681 return; 682 } 683 } 684 } 685 686 /* 687 * Check that a proposed value to load into the .it_value or 688 * .it_interval part of an interval timer is acceptable. 689 */ 690 int 691 itimerfix(struct timeval *tv) 692 { 693 694 if (tv->tv_sec < 0 || tv->tv_sec > 100000000 || 695 tv->tv_usec < 0 || tv->tv_usec >= 1000000) 696 return (EINVAL); 697 698 if (tv->tv_sec == 0 && tv->tv_usec != 0 && tv->tv_usec < tick) 699 tv->tv_usec = tick; 700 701 return (0); 702 } 703 704 /* 705 * Nonzero timer interval smaller than the resolution of the 706 * system clock are rounded up. 707 */ 708 void 709 itimerround(struct timeval *tv) 710 { 711 if (tv->tv_sec == 0 && tv->tv_usec != 0 && tv->tv_usec < tick) 712 tv->tv_usec = tick; 713 } 714 715 /* 716 * Decrement an interval timer by a specified number 717 * of microseconds, which must be less than a second, 718 * i.e. < 1000000. If the timer expires, then reload 719 * it. In this case, carry over (usec - old value) to 720 * reduce the value reloaded into the timer so that 721 * the timer does not drift. This routine assumes 722 * that it is called in a context where the timers 723 * on which it is operating cannot change in value. 724 */ 725 int 726 itimerdecr(struct itimerval *itp, int usec) 727 { 728 729 if (itp->it_value.tv_usec < usec) { 730 if (itp->it_value.tv_sec == 0) { 731 /* expired, and already in next interval */ 732 usec -= itp->it_value.tv_usec; 733 goto expire; 734 } 735 itp->it_value.tv_usec += 1000000; 736 itp->it_value.tv_sec--; 737 } 738 itp->it_value.tv_usec -= usec; 739 usec = 0; 740 if (timerisset(&itp->it_value)) 741 return (1); 742 /* expired, exactly at end of interval */ 743 expire: 744 if (timerisset(&itp->it_interval)) { 745 itp->it_value = itp->it_interval; 746 itp->it_value.tv_usec -= usec; 747 if (itp->it_value.tv_usec < 0) { 748 itp->it_value.tv_usec += 1000000; 749 itp->it_value.tv_sec--; 750 } 751 } else 752 itp->it_value.tv_usec = 0; /* sec is already 0 */ 753 return (0); 754 } 755 756 /* 757 * ratecheck(): simple time-based rate-limit checking. see ratecheck(9) 758 * for usage and rationale. 759 */ 760 int 761 ratecheck(struct timeval *lasttime, const struct timeval *mininterval) 762 { 763 struct timeval tv, delta; 764 int rv = 0; 765 766 getmicrouptime(&tv); 767 768 timersub(&tv, lasttime, &delta); 769 770 /* 771 * check for 0,0 is so that the message will be seen at least once, 772 * even if interval is huge. 773 */ 774 if (timercmp(&delta, mininterval, >=) || 775 (lasttime->tv_sec == 0 && lasttime->tv_usec == 0)) { 776 *lasttime = tv; 777 rv = 1; 778 } 779 780 return (rv); 781 } 782 783 /* 784 * ppsratecheck(): packets (or events) per second limitation. 785 */ 786 int 787 ppsratecheck(struct timeval *lasttime, int *curpps, int maxpps) 788 { 789 struct timeval tv, delta; 790 int rv; 791 792 microuptime(&tv); 793 794 timersub(&tv, lasttime, &delta); 795 796 /* 797 * check for 0,0 is so that the message will be seen at least once. 798 * if more than one second have passed since the last update of 799 * lasttime, reset the counter. 800 * 801 * we do increment *curpps even in *curpps < maxpps case, as some may 802 * try to use *curpps for stat purposes as well. 803 */ 804 if (maxpps == 0) 805 rv = 0; 806 else if ((lasttime->tv_sec == 0 && lasttime->tv_usec == 0) || 807 delta.tv_sec >= 1) { 808 *lasttime = tv; 809 *curpps = 0; 810 rv = 1; 811 } else if (maxpps < 0) 812 rv = 1; 813 else if (*curpps < maxpps) 814 rv = 1; 815 else 816 rv = 0; 817 818 #if 1 /*DIAGNOSTIC?*/ 819 /* be careful about wrap-around */ 820 if (*curpps + 1 > *curpps) 821 *curpps = *curpps + 1; 822 #else 823 /* 824 * assume that there's not too many calls to this function. 825 * not sure if the assumption holds, as it depends on *caller's* 826 * behavior, not the behavior of this function. 827 * IMHO it is wrong to make assumption on the caller's behavior, 828 * so the above #if is #if 1, not #ifdef DIAGNOSTIC. 829 */ 830 *curpps = *curpps + 1; 831 #endif 832 833 return (rv); 834 } 835