1 /* 2 * Copyright (c) 1982, 1986, 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 4. Neither the name of the University nor the names of its contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * @(#)kern_time.c 8.1 (Berkeley) 6/10/93 30 */ 31 32 #include <sys/cdefs.h> 33 __FBSDID("$FreeBSD$"); 34 35 #include "opt_mac.h" 36 37 #include <sys/param.h> 38 #include <sys/systm.h> 39 #include <sys/lock.h> 40 #include <sys/mutex.h> 41 #include <sys/sysproto.h> 42 #include <sys/resourcevar.h> 43 #include <sys/signalvar.h> 44 #include <sys/kernel.h> 45 #include <sys/mac.h> 46 #include <sys/sysent.h> 47 #include <sys/proc.h> 48 #include <sys/time.h> 49 #include <sys/timetc.h> 50 #include <sys/vnode.h> 51 52 #include <vm/vm.h> 53 #include <vm/vm_extern.h> 54 55 int tz_minuteswest; 56 int tz_dsttime; 57 58 /* 59 * Time of day and interval timer support. 60 * 61 * These routines provide the kernel entry points to get and set 62 * the time-of-day and per-process interval timers. Subroutines 63 * here provide support for adding and subtracting timeval structures 64 * and decrementing interval timers, optionally reloading the interval 65 * timers when they expire. 66 */ 67 68 static int nanosleep1(struct thread *td, struct timespec *rqt, 69 struct timespec *rmt); 70 static int settime(struct thread *, struct timeval *); 71 static void timevalfix(struct timeval *); 72 static void no_lease_updatetime(int); 73 74 static void 75 no_lease_updatetime(deltat) 76 int deltat; 77 { 78 } 79 80 void (*lease_updatetime)(int) = no_lease_updatetime; 81 82 static int 83 settime(struct thread *td, struct timeval *tv) 84 { 85 struct timeval delta, tv1, tv2; 86 static struct timeval maxtime, laststep; 87 struct timespec ts; 88 int s; 89 90 s = splclock(); 91 microtime(&tv1); 92 delta = *tv; 93 timevalsub(&delta, &tv1); 94 95 /* 96 * If the system is secure, we do not allow the time to be 97 * set to a value earlier than 1 second less than the highest 98 * time we have yet seen. The worst a miscreant can do in 99 * this circumstance is "freeze" time. He couldn't go 100 * back to the past. 101 * 102 * We similarly do not allow the clock to be stepped more 103 * than one second, nor more than once per second. This allows 104 * a miscreant to make the clock march double-time, but no worse. 105 */ 106 if (securelevel_gt(td->td_ucred, 1) != 0) { 107 if (delta.tv_sec < 0 || delta.tv_usec < 0) { 108 /* 109 * Update maxtime to latest time we've seen. 110 */ 111 if (tv1.tv_sec > maxtime.tv_sec) 112 maxtime = tv1; 113 tv2 = *tv; 114 timevalsub(&tv2, &maxtime); 115 if (tv2.tv_sec < -1) { 116 tv->tv_sec = maxtime.tv_sec - 1; 117 printf("Time adjustment clamped to -1 second\n"); 118 } 119 } else { 120 if (tv1.tv_sec == laststep.tv_sec) { 121 splx(s); 122 return (EPERM); 123 } 124 if (delta.tv_sec > 1) { 125 tv->tv_sec = tv1.tv_sec + 1; 126 printf("Time adjustment clamped to +1 second\n"); 127 } 128 laststep = *tv; 129 } 130 } 131 132 ts.tv_sec = tv->tv_sec; 133 ts.tv_nsec = tv->tv_usec * 1000; 134 mtx_lock(&Giant); 135 tc_setclock(&ts); 136 (void) splsoftclock(); 137 lease_updatetime(delta.tv_sec); 138 splx(s); 139 resettodr(); 140 mtx_unlock(&Giant); 141 return (0); 142 } 143 144 #ifndef _SYS_SYSPROTO_H_ 145 struct clock_gettime_args { 146 clockid_t clock_id; 147 struct timespec *tp; 148 }; 149 #endif 150 151 /* 152 * MPSAFE 153 */ 154 /* ARGSUSED */ 155 int 156 clock_gettime(struct thread *td, struct clock_gettime_args *uap) 157 { 158 struct timespec ats; 159 struct timeval sys, user; 160 161 switch (uap->clock_id) { 162 case CLOCK_REALTIME: 163 nanotime(&ats); 164 break; 165 case CLOCK_VIRTUAL: 166 mtx_lock_spin(&sched_lock); 167 calcru(td->td_proc, &user, &sys, NULL); 168 mtx_unlock_spin(&sched_lock); 169 TIMEVAL_TO_TIMESPEC(&user, &ats); 170 break; 171 case CLOCK_PROF: 172 mtx_lock_spin(&sched_lock); 173 calcru(td->td_proc, &user, &sys, NULL); 174 mtx_unlock_spin(&sched_lock); 175 timevaladd(&user, &sys); 176 TIMEVAL_TO_TIMESPEC(&user, &ats); 177 break; 178 case CLOCK_MONOTONIC: 179 nanouptime(&ats); 180 break; 181 default: 182 return (EINVAL); 183 } 184 return (copyout(&ats, uap->tp, sizeof(ats))); 185 } 186 187 #ifndef _SYS_SYSPROTO_H_ 188 struct clock_settime_args { 189 clockid_t clock_id; 190 const struct timespec *tp; 191 }; 192 #endif 193 194 /* 195 * MPSAFE 196 */ 197 /* ARGSUSED */ 198 int 199 clock_settime(struct thread *td, struct clock_settime_args *uap) 200 { 201 struct timeval atv; 202 struct timespec ats; 203 int error; 204 205 #ifdef MAC 206 error = mac_check_system_settime(td->td_ucred); 207 if (error) 208 return (error); 209 #endif 210 if ((error = suser(td)) != 0) 211 return (error); 212 if (uap->clock_id != CLOCK_REALTIME) 213 return (EINVAL); 214 if ((error = copyin(uap->tp, &ats, sizeof(ats))) != 0) 215 return (error); 216 if (ats.tv_nsec < 0 || ats.tv_nsec >= 1000000000) 217 return (EINVAL); 218 /* XXX Don't convert nsec->usec and back */ 219 TIMESPEC_TO_TIMEVAL(&atv, &ats); 220 error = settime(td, &atv); 221 return (error); 222 } 223 224 #ifndef _SYS_SYSPROTO_H_ 225 struct clock_getres_args { 226 clockid_t clock_id; 227 struct timespec *tp; 228 }; 229 #endif 230 231 int 232 clock_getres(struct thread *td, struct clock_getres_args *uap) 233 { 234 struct timespec ts; 235 236 ts.tv_sec = 0; 237 switch (uap->clock_id) { 238 case CLOCK_REALTIME: 239 case CLOCK_MONOTONIC: 240 /* 241 * Round up the result of the division cheaply by adding 1. 242 * Rounding up is especially important if rounding down 243 * would give 0. Perfect rounding is unimportant. 244 */ 245 ts.tv_nsec = 1000000000 / tc_getfrequency() + 1; 246 break; 247 case CLOCK_VIRTUAL: 248 case CLOCK_PROF: 249 /* Accurately round up here because we can do so cheaply. */ 250 ts.tv_nsec = (1000000000 + hz - 1) / hz; 251 break; 252 default: 253 return (EINVAL); 254 } 255 if (uap->tp == NULL) 256 return (0); 257 return (copyout(&ts, uap->tp, sizeof(ts))); 258 } 259 260 static int nanowait; 261 262 static int 263 nanosleep1(struct thread *td, struct timespec *rqt, struct timespec *rmt) 264 { 265 struct timespec ts, ts2, ts3; 266 struct timeval tv; 267 int error; 268 269 if (rqt->tv_nsec < 0 || rqt->tv_nsec >= 1000000000) 270 return (EINVAL); 271 if (rqt->tv_sec < 0 || (rqt->tv_sec == 0 && rqt->tv_nsec == 0)) 272 return (0); 273 getnanouptime(&ts); 274 timespecadd(&ts, rqt); 275 TIMESPEC_TO_TIMEVAL(&tv, rqt); 276 for (;;) { 277 error = tsleep(&nanowait, PWAIT | PCATCH, "nanslp", 278 tvtohz(&tv)); 279 getnanouptime(&ts2); 280 if (error != EWOULDBLOCK) { 281 if (error == ERESTART) 282 error = EINTR; 283 if (rmt != NULL) { 284 timespecsub(&ts, &ts2); 285 if (ts.tv_sec < 0) 286 timespecclear(&ts); 287 *rmt = ts; 288 } 289 return (error); 290 } 291 if (timespeccmp(&ts2, &ts, >=)) 292 return (0); 293 ts3 = ts; 294 timespecsub(&ts3, &ts2); 295 TIMESPEC_TO_TIMEVAL(&tv, &ts3); 296 } 297 } 298 299 #ifndef _SYS_SYSPROTO_H_ 300 struct nanosleep_args { 301 struct timespec *rqtp; 302 struct timespec *rmtp; 303 }; 304 #endif 305 306 /* 307 * MPSAFE 308 */ 309 /* ARGSUSED */ 310 int 311 nanosleep(struct thread *td, struct nanosleep_args *uap) 312 { 313 struct timespec rmt, rqt; 314 int error; 315 316 error = copyin(uap->rqtp, &rqt, sizeof(rqt)); 317 if (error) 318 return (error); 319 320 if (uap->rmtp && 321 !useracc((caddr_t)uap->rmtp, sizeof(rmt), VM_PROT_WRITE)) 322 return (EFAULT); 323 error = nanosleep1(td, &rqt, &rmt); 324 if (error && uap->rmtp) { 325 int error2; 326 327 error2 = copyout(&rmt, uap->rmtp, sizeof(rmt)); 328 if (error2) 329 error = error2; 330 } 331 return (error); 332 } 333 334 #ifndef _SYS_SYSPROTO_H_ 335 struct gettimeofday_args { 336 struct timeval *tp; 337 struct timezone *tzp; 338 }; 339 #endif 340 /* 341 * MPSAFE 342 */ 343 /* ARGSUSED */ 344 int 345 gettimeofday(struct thread *td, struct gettimeofday_args *uap) 346 { 347 struct timeval atv; 348 struct timezone rtz; 349 int error = 0; 350 351 if (uap->tp) { 352 microtime(&atv); 353 error = copyout(&atv, uap->tp, sizeof (atv)); 354 } 355 if (error == 0 && uap->tzp != NULL) { 356 rtz.tz_minuteswest = tz_minuteswest; 357 rtz.tz_dsttime = tz_dsttime; 358 error = copyout(&rtz, uap->tzp, sizeof (rtz)); 359 } 360 return (error); 361 } 362 363 #ifndef _SYS_SYSPROTO_H_ 364 struct settimeofday_args { 365 struct timeval *tv; 366 struct timezone *tzp; 367 }; 368 #endif 369 /* 370 * MPSAFE 371 */ 372 /* ARGSUSED */ 373 int 374 settimeofday(struct thread *td, struct settimeofday_args *uap) 375 { 376 struct timeval atv; 377 struct timezone atz; 378 int error = 0; 379 380 #ifdef MAC 381 error = mac_check_system_settime(td->td_ucred); 382 if (error) 383 return (error); 384 #endif 385 if ((error = suser(td))) 386 return (error); 387 /* Verify all parameters before changing time. */ 388 if (uap->tv) { 389 if ((error = copyin(uap->tv, &atv, sizeof(atv)))) 390 return (error); 391 if (atv.tv_usec < 0 || atv.tv_usec >= 1000000) 392 return (EINVAL); 393 } 394 if (uap->tzp && 395 (error = copyin(uap->tzp, &atz, sizeof(atz)))) 396 return (error); 397 398 if (uap->tv && (error = settime(td, &atv))) 399 return (error); 400 if (uap->tzp) { 401 tz_minuteswest = atz.tz_minuteswest; 402 tz_dsttime = atz.tz_dsttime; 403 } 404 return (error); 405 } 406 /* 407 * Get value of an interval timer. The process virtual and 408 * profiling virtual time timers are kept in the p_stats area, since 409 * they can be swapped out. These are kept internally in the 410 * way they are specified externally: in time until they expire. 411 * 412 * The real time interval timer is kept in the process table slot 413 * for the process, and its value (it_value) is kept as an 414 * absolute time rather than as a delta, so that it is easy to keep 415 * periodic real-time signals from drifting. 416 * 417 * Virtual time timers are processed in the hardclock() routine of 418 * kern_clock.c. The real time timer is processed by a timeout 419 * routine, called from the softclock() routine. Since a callout 420 * may be delayed in real time due to interrupt processing in the system, 421 * it is possible for the real time timeout routine (realitexpire, given below), 422 * to be delayed in real time past when it is supposed to occur. It 423 * does not suffice, therefore, to reload the real timer .it_value from the 424 * real time timers .it_interval. Rather, we compute the next time in 425 * absolute time the timer should go off. 426 */ 427 #ifndef _SYS_SYSPROTO_H_ 428 struct getitimer_args { 429 u_int which; 430 struct itimerval *itv; 431 }; 432 #endif 433 /* 434 * MPSAFE 435 */ 436 int 437 getitimer(struct thread *td, struct getitimer_args *uap) 438 { 439 struct proc *p = td->td_proc; 440 struct timeval ctv; 441 struct itimerval aitv; 442 443 if (uap->which > ITIMER_PROF) 444 return (EINVAL); 445 446 if (uap->which == ITIMER_REAL) { 447 /* 448 * Convert from absolute to relative time in .it_value 449 * part of real time timer. If time for real time timer 450 * has passed return 0, else return difference between 451 * current time and time for the timer to go off. 452 */ 453 PROC_LOCK(p); 454 aitv = p->p_realtimer; 455 PROC_UNLOCK(p); 456 if (timevalisset(&aitv.it_value)) { 457 getmicrouptime(&ctv); 458 if (timevalcmp(&aitv.it_value, &ctv, <)) 459 timevalclear(&aitv.it_value); 460 else 461 timevalsub(&aitv.it_value, &ctv); 462 } 463 } else { 464 mtx_lock_spin(&sched_lock); 465 aitv = p->p_stats->p_timer[uap->which]; 466 mtx_unlock_spin(&sched_lock); 467 } 468 return (copyout(&aitv, uap->itv, sizeof (struct itimerval))); 469 } 470 471 #ifndef _SYS_SYSPROTO_H_ 472 struct setitimer_args { 473 u_int which; 474 struct itimerval *itv, *oitv; 475 }; 476 #endif 477 /* 478 * MPSAFE 479 */ 480 int 481 setitimer(struct thread *td, struct setitimer_args *uap) 482 { 483 struct proc *p = td->td_proc; 484 struct itimerval aitv, oitv; 485 struct timeval ctv; 486 int error; 487 488 if (uap->itv == NULL) { 489 uap->itv = uap->oitv; 490 return (getitimer(td, (struct getitimer_args *)uap)); 491 } 492 493 if (uap->which > ITIMER_PROF) 494 return (EINVAL); 495 if ((error = copyin(uap->itv, &aitv, sizeof(struct itimerval)))) 496 return (error); 497 if (itimerfix(&aitv.it_value)) 498 return (EINVAL); 499 if (!timevalisset(&aitv.it_value)) 500 timevalclear(&aitv.it_interval); 501 else if (itimerfix(&aitv.it_interval)) 502 return (EINVAL); 503 504 if (uap->which == ITIMER_REAL) { 505 PROC_LOCK(p); 506 if (timevalisset(&p->p_realtimer.it_value)) 507 callout_stop(&p->p_itcallout); 508 getmicrouptime(&ctv); 509 if (timevalisset(&aitv.it_value)) { 510 callout_reset(&p->p_itcallout, tvtohz(&aitv.it_value), 511 realitexpire, p); 512 timevaladd(&aitv.it_value, &ctv); 513 } 514 oitv = p->p_realtimer; 515 p->p_realtimer = aitv; 516 PROC_UNLOCK(p); 517 if (timevalisset(&oitv.it_value)) { 518 if (timevalcmp(&oitv.it_value, &ctv, <)) 519 timevalclear(&oitv.it_value); 520 else 521 timevalsub(&oitv.it_value, &ctv); 522 } 523 } else { 524 mtx_lock_spin(&sched_lock); 525 oitv = p->p_stats->p_timer[uap->which]; 526 p->p_stats->p_timer[uap->which] = aitv; 527 mtx_unlock_spin(&sched_lock); 528 } 529 if (uap->oitv == NULL) 530 return (0); 531 return (copyout(&oitv, uap->oitv, sizeof(struct itimerval))); 532 } 533 534 /* 535 * Real interval timer expired: 536 * send process whose timer expired an alarm signal. 537 * If time is not set up to reload, then just return. 538 * Else compute next time timer should go off which is > current time. 539 * This is where delay in processing this timeout causes multiple 540 * SIGALRM calls to be compressed into one. 541 * tvtohz() always adds 1 to allow for the time until the next clock 542 * interrupt being strictly less than 1 clock tick, but we don't want 543 * that here since we want to appear to be in sync with the clock 544 * interrupt even when we're delayed. 545 */ 546 void 547 realitexpire(void *arg) 548 { 549 struct proc *p; 550 struct timeval ctv, ntv; 551 552 p = (struct proc *)arg; 553 PROC_LOCK(p); 554 psignal(p, SIGALRM); 555 if (!timevalisset(&p->p_realtimer.it_interval)) { 556 timevalclear(&p->p_realtimer.it_value); 557 if (p->p_flag & P_WEXIT) 558 wakeup(&p->p_itcallout); 559 PROC_UNLOCK(p); 560 return; 561 } 562 for (;;) { 563 timevaladd(&p->p_realtimer.it_value, 564 &p->p_realtimer.it_interval); 565 getmicrouptime(&ctv); 566 if (timevalcmp(&p->p_realtimer.it_value, &ctv, >)) { 567 ntv = p->p_realtimer.it_value; 568 timevalsub(&ntv, &ctv); 569 callout_reset(&p->p_itcallout, tvtohz(&ntv) - 1, 570 realitexpire, p); 571 PROC_UNLOCK(p); 572 return; 573 } 574 } 575 /*NOTREACHED*/ 576 } 577 578 /* 579 * Check that a proposed value to load into the .it_value or 580 * .it_interval part of an interval timer is acceptable, and 581 * fix it to have at least minimal value (i.e. if it is less 582 * than the resolution of the clock, round it up.) 583 */ 584 int 585 itimerfix(struct timeval *tv) 586 { 587 588 if (tv->tv_sec < 0 || tv->tv_sec > 100000000 || 589 tv->tv_usec < 0 || tv->tv_usec >= 1000000) 590 return (EINVAL); 591 if (tv->tv_sec == 0 && tv->tv_usec != 0 && tv->tv_usec < tick) 592 tv->tv_usec = tick; 593 return (0); 594 } 595 596 /* 597 * Decrement an interval timer by a specified number 598 * of microseconds, which must be less than a second, 599 * i.e. < 1000000. If the timer expires, then reload 600 * it. In this case, carry over (usec - old value) to 601 * reduce the value reloaded into the timer so that 602 * the timer does not drift. This routine assumes 603 * that it is called in a context where the timers 604 * on which it is operating cannot change in value. 605 */ 606 int 607 itimerdecr(struct itimerval *itp, int usec) 608 { 609 610 if (itp->it_value.tv_usec < usec) { 611 if (itp->it_value.tv_sec == 0) { 612 /* expired, and already in next interval */ 613 usec -= itp->it_value.tv_usec; 614 goto expire; 615 } 616 itp->it_value.tv_usec += 1000000; 617 itp->it_value.tv_sec--; 618 } 619 itp->it_value.tv_usec -= usec; 620 usec = 0; 621 if (timevalisset(&itp->it_value)) 622 return (1); 623 /* expired, exactly at end of interval */ 624 expire: 625 if (timevalisset(&itp->it_interval)) { 626 itp->it_value = itp->it_interval; 627 itp->it_value.tv_usec -= usec; 628 if (itp->it_value.tv_usec < 0) { 629 itp->it_value.tv_usec += 1000000; 630 itp->it_value.tv_sec--; 631 } 632 } else 633 itp->it_value.tv_usec = 0; /* sec is already 0 */ 634 return (0); 635 } 636 637 /* 638 * Add and subtract routines for timevals. 639 * N.B.: subtract routine doesn't deal with 640 * results which are before the beginning, 641 * it just gets very confused in this case. 642 * Caveat emptor. 643 */ 644 void 645 timevaladd(struct timeval *t1, const struct timeval *t2) 646 { 647 648 t1->tv_sec += t2->tv_sec; 649 t1->tv_usec += t2->tv_usec; 650 timevalfix(t1); 651 } 652 653 void 654 timevalsub(struct timeval *t1, const struct timeval *t2) 655 { 656 657 t1->tv_sec -= t2->tv_sec; 658 t1->tv_usec -= t2->tv_usec; 659 timevalfix(t1); 660 } 661 662 static void 663 timevalfix(struct timeval *t1) 664 { 665 666 if (t1->tv_usec < 0) { 667 t1->tv_sec--; 668 t1->tv_usec += 1000000; 669 } 670 if (t1->tv_usec >= 1000000) { 671 t1->tv_sec++; 672 t1->tv_usec -= 1000000; 673 } 674 } 675 676 /* 677 * ratecheck(): simple time-based rate-limit checking. 678 */ 679 int 680 ratecheck(struct timeval *lasttime, const struct timeval *mininterval) 681 { 682 struct timeval tv, delta; 683 int rv = 0; 684 685 getmicrouptime(&tv); /* NB: 10ms precision */ 686 delta = tv; 687 timevalsub(&delta, lasttime); 688 689 /* 690 * check for 0,0 is so that the message will be seen at least once, 691 * even if interval is huge. 692 */ 693 if (timevalcmp(&delta, mininterval, >=) || 694 (lasttime->tv_sec == 0 && lasttime->tv_usec == 0)) { 695 *lasttime = tv; 696 rv = 1; 697 } 698 699 return (rv); 700 } 701 702 /* 703 * ppsratecheck(): packets (or events) per second limitation. 704 * 705 * Return 0 if the limit is to be enforced (e.g. the caller 706 * should drop a packet because of the rate limitation). 707 * 708 * maxpps of 0 always causes zero to be returned. maxpps of -1 709 * always causes 1 to be returned; this effectively defeats rate 710 * limiting. 711 * 712 * Note that we maintain the struct timeval for compatibility 713 * with other bsd systems. We reuse the storage and just monitor 714 * clock ticks for minimal overhead. 715 */ 716 int 717 ppsratecheck(struct timeval *lasttime, int *curpps, int maxpps) 718 { 719 int now; 720 721 /* 722 * Reset the last time and counter if this is the first call 723 * or more than a second has passed since the last update of 724 * lasttime. 725 */ 726 now = ticks; 727 if (lasttime->tv_sec == 0 || (u_int)(now - lasttime->tv_sec) >= hz) { 728 lasttime->tv_sec = now; 729 *curpps = 1; 730 return (maxpps != 0); 731 } else { 732 (*curpps)++; /* NB: ignore potential overflow */ 733 return (maxpps < 0 || *curpps < maxpps); 734 } 735 } 736