kern_time.c revision 1.129
1/* $NetBSD: kern_time.c,v 1.129 2007/10/08 20:06:19 ad Exp $ */ 2 3/*- 4 * Copyright (c) 2000, 2004, 2005 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Christopher G. Demetriou. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39/* 40 * Copyright (c) 1982, 1986, 1989, 1993 41 * The Regents of the University of California. All rights reserved. 42 * 43 * Redistribution and use in source and binary forms, with or without 44 * modification, are permitted provided that the following conditions 45 * are met: 46 * 1. Redistributions of source code must retain the above copyright 47 * notice, this list of conditions and the following disclaimer. 48 * 2. Redistributions in binary form must reproduce the above copyright 49 * notice, this list of conditions and the following disclaimer in the 50 * documentation and/or other materials provided with the distribution. 51 * 3. Neither the name of the University nor the names of its contributors 52 * may be used to endorse or promote products derived from this software 53 * without specific prior written permission. 54 * 55 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 56 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 57 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 58 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 59 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 60 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 61 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 62 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 63 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 64 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 65 * SUCH DAMAGE. 66 * 67 * @(#)kern_time.c 8.4 (Berkeley) 5/26/95 68 */ 69 70#include <sys/cdefs.h> 71__KERNEL_RCSID(0, "$NetBSD: kern_time.c,v 1.129 2007/10/08 20:06:19 ad Exp $"); 72 73#include <sys/param.h> 74#include <sys/resourcevar.h> 75#include <sys/kernel.h> 76#include <sys/systm.h> 77#include <sys/proc.h> 78#include <sys/vnode.h> 79#include <sys/signalvar.h> 80#include <sys/syslog.h> 81#include <sys/timetc.h> 82#ifndef __HAVE_TIMECOUNTER 83#include <sys/timevar.h> 84#endif /* !__HAVE_TIMECOUNTER */ 85#include <sys/kauth.h> 86 87#include <sys/mount.h> 88#include <sys/syscallargs.h> 89 90#include <uvm/uvm_extern.h> 91 92#include <machine/cpu.h> 93 94POOL_INIT(ptimer_pool, sizeof(struct ptimer), 0, 0, 0, "ptimerpl", 95 &pool_allocator_nointr, IPL_NONE); 96POOL_INIT(ptimers_pool, sizeof(struct ptimers), 0, 0, 0, "ptimerspl", 97 &pool_allocator_nointr, IPL_NONE); 98 99/* Time of day and interval timer support. 100 * 101 * These routines provide the kernel entry points to get and set 102 * the time-of-day and per-process interval timers. Subroutines 103 * here provide support for adding and subtracting timeval structures 104 * and decrementing interval timers, optionally reloading the interval 105 * timers when they expire. 106 */ 107 108/* This function is used by clock_settime and settimeofday */ 109int 110settime(struct proc *p, struct timespec *ts) 111{ 112 struct timeval delta, tv; 113#ifdef __HAVE_TIMECOUNTER 114 struct timeval now; 115 struct timespec ts1; 116#endif /* !__HAVE_TIMECOUNTER */ 117 lwp_t *l; 118 int s; 119 120 /* 121 * Don't allow the time to be set forward so far it will wrap 122 * and become negative, thus allowing an attacker to bypass 123 * the next check below. The cutoff is 1 year before rollover 124 * occurs, so even if the attacker uses adjtime(2) to move 125 * the time past the cutoff, it will take a very long time 126 * to get to the wrap point. 127 * 128 * XXX: we check against INT_MAX since on 64-bit 129 * platforms, sizeof(int) != sizeof(long) and 130 * time_t is 32 bits even when atv.tv_sec is 64 bits. 131 */ 132 if (ts->tv_sec > INT_MAX - 365*24*60*60) { 133 struct proc *pp; 134 135 mutex_enter(&proclist_lock); 136 pp = p->p_pptr; 137 mutex_enter(&pp->p_mutex); 138 log(LOG_WARNING, "pid %d (%s) " 139 "invoked by uid %d ppid %d (%s) " 140 "tried to set clock forward to %ld\n", 141 p->p_pid, p->p_comm, kauth_cred_geteuid(pp->p_cred), 142 pp->p_pid, pp->p_comm, (long)ts->tv_sec); 143 mutex_exit(&pp->p_mutex); 144 mutex_exit(&proclist_lock); 145 return (EPERM); 146 } 147 TIMESPEC_TO_TIMEVAL(&tv, ts); 148 149 /* WHAT DO WE DO ABOUT PENDING REAL-TIME TIMEOUTS??? */ 150 s = splclock(); 151#ifdef __HAVE_TIMECOUNTER 152 microtime(&now); 153 timersub(&tv, &now, &delta); 154#else /* !__HAVE_TIMECOUNTER */ 155 timersub(&tv, &time, &delta); 156#endif /* !__HAVE_TIMECOUNTER */ 157 if ((delta.tv_sec < 0 || delta.tv_usec < 0) && 158 kauth_authorize_system(p->p_cred, KAUTH_SYSTEM_TIME, 159 KAUTH_REQ_SYSTEM_TIME_BACKWARDS, NULL, NULL, NULL)) { 160 splx(s); 161 return (EPERM); 162 } 163#ifdef notyet 164 if ((delta.tv_sec < 86400) && securelevel > 0) { /* XXX elad - notyet */ 165 splx(s); 166 return (EPERM); 167 } 168#endif 169 170#ifdef __HAVE_TIMECOUNTER 171 TIMEVAL_TO_TIMESPEC(&tv, &ts1); 172 tc_setclock(&ts1); 173#else /* !__HAVE_TIMECOUNTER */ 174 time = tv; 175#endif /* !__HAVE_TIMECOUNTER */ 176 177 timeradd(&boottime, &delta, &boottime); 178 179 /* 180 * XXXSMP: There is a short race between setting the time above 181 * and adjusting LWP's run times. Fixing this properly means 182 * pausing all CPUs while we adjust the clock. 183 */ 184 mutex_enter(&proclist_lock); 185 LIST_FOREACH(l, &alllwp, l_list) { 186 lwp_lock(l); 187 timeradd(&l->l_stime, &delta, &l->l_stime); 188 lwp_unlock(l); 189 } 190 mutex_exit(&proclist_lock); 191 resettodr(); 192 splx(s); 193 194 return (0); 195} 196 197/* ARGSUSED */ 198int 199sys_clock_gettime(struct lwp *l, void *v, register_t *retval) 200{ 201 struct sys_clock_gettime_args /* { 202 syscallarg(clockid_t) clock_id; 203 syscallarg(struct timespec *) tp; 204 } */ *uap = v; 205 clockid_t clock_id; 206 struct timespec ats; 207 208 clock_id = SCARG(uap, clock_id); 209 switch (clock_id) { 210 case CLOCK_REALTIME: 211 nanotime(&ats); 212 break; 213 case CLOCK_MONOTONIC: 214 nanouptime(&ats); 215 break; 216 default: 217 return (EINVAL); 218 } 219 220 return copyout(&ats, SCARG(uap, tp), sizeof(ats)); 221} 222 223/* ARGSUSED */ 224int 225sys_clock_settime(struct lwp *l, void *v, register_t *retval) 226{ 227 struct sys_clock_settime_args /* { 228 syscallarg(clockid_t) clock_id; 229 syscallarg(const struct timespec *) tp; 230 } */ *uap = v; 231 int error; 232 233 if ((error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_TIME, 234 KAUTH_REQ_SYSTEM_TIME_SYSTEM, NULL, NULL, NULL)) != 0) 235 return (error); 236 237 return clock_settime1(l->l_proc, SCARG(uap, clock_id), SCARG(uap, tp)); 238} 239 240 241int 242clock_settime1(struct proc *p, clockid_t clock_id, const struct timespec *tp) 243{ 244 struct timespec ats; 245 int error; 246 247 if ((error = copyin(tp, &ats, sizeof(ats))) != 0) 248 return (error); 249 250 switch (clock_id) { 251 case CLOCK_REALTIME: 252 if ((error = settime(p, &ats)) != 0) 253 return (error); 254 break; 255 case CLOCK_MONOTONIC: 256 return (EINVAL); /* read-only clock */ 257 default: 258 return (EINVAL); 259 } 260 261 return 0; 262} 263 264int 265sys_clock_getres(struct lwp *l, void *v, register_t *retval) 266{ 267 struct sys_clock_getres_args /* { 268 syscallarg(clockid_t) clock_id; 269 syscallarg(struct timespec *) tp; 270 } */ *uap = v; 271 clockid_t clock_id; 272 struct timespec ts; 273 int error = 0; 274 275 clock_id = SCARG(uap, clock_id); 276 switch (clock_id) { 277 case CLOCK_REALTIME: 278 case CLOCK_MONOTONIC: 279 ts.tv_sec = 0; 280 if (tc_getfrequency() > 1000000000) 281 ts.tv_nsec = 1; 282 else 283 ts.tv_nsec = 1000000000 / tc_getfrequency(); 284 break; 285 default: 286 return (EINVAL); 287 } 288 289 if (SCARG(uap, tp)) 290 error = copyout(&ts, SCARG(uap, tp), sizeof(ts)); 291 292 return error; 293} 294 295/* ARGSUSED */ 296int 297sys_nanosleep(struct lwp *l, void *v, register_t *retval) 298{ 299 struct sys_nanosleep_args/* { 300 syscallarg(struct timespec *) rqtp; 301 syscallarg(struct timespec *) rmtp; 302 } */ *uap = v; 303 struct timespec rmt, rqt; 304 int error, error1; 305 306 error = copyin(SCARG(uap, rqtp), &rqt, sizeof(struct timespec)); 307 if (error) 308 return (error); 309 310 error = nanosleep1(l, &rqt, SCARG(uap, rmtp) ? &rmt : NULL); 311 if (SCARG(uap, rmtp) == NULL || (error != 0 && error != EINTR)) 312 return error; 313 314 error1 = copyout(&rmt, SCARG(uap, rmtp), sizeof(rmt)); 315 return error1 ? error1 : error; 316} 317 318int 319nanosleep1(struct lwp *l, struct timespec *rqt, struct timespec *rmt) 320{ 321#ifdef __HAVE_TIMECOUNTER 322 int error, timo; 323 324 if (itimespecfix(rqt)) 325 return (EINVAL); 326 327 timo = tstohz(rqt); 328 /* 329 * Avoid inadvertantly sleeping forever 330 */ 331 if (timo == 0) 332 timo = 1; 333 334 if (rmt != NULL) 335 getnanouptime(rmt); 336 337 error = kpause("nanoslp", true, timo, NULL); 338 if (error == ERESTART) 339 error = EINTR; 340 if (error == EWOULDBLOCK) 341 error = 0; 342 343 if (rmt!= NULL) { 344 struct timespec rmtend; 345 346 getnanouptime(&rmtend); 347 348 timespecsub(&rmtend, rmt, rmt); 349 timespecsub(rqt, rmt, rmt); 350 if (rmt->tv_sec < 0) 351 timespecclear(rmt); 352 } 353 354 return error; 355#else /* !__HAVE_TIMECOUNTER */ 356 struct timeval atv, utv; 357 int error, s, timo; 358 359 TIMESPEC_TO_TIMEVAL(&atv, rqt); 360 if (itimerfix(&atv)) 361 return (EINVAL); 362 363 s = splclock(); 364 timeradd(&atv,&time,&atv); 365 timo = hzto(&atv); 366 /* 367 * Avoid inadvertantly sleeping forever 368 */ 369 if (timo == 0) 370 timo = 1; 371 splx(s); 372 373 error = kpause("nanoslp", true, timo, NULL); 374 if (error == ERESTART) 375 error = EINTR; 376 if (error == EWOULDBLOCK) 377 error = 0; 378 379 if (rmt != NULL) { 380 s = splclock(); 381 utv = time; 382 splx(s); 383 384 timersub(&atv, &utv, &utv); 385 if (utv.tv_sec < 0) 386 timerclear(&utv); 387 388 TIMEVAL_TO_TIMESPEC(&utv, rmt); 389 } 390 391 return error; 392#endif /* !__HAVE_TIMECOUNTER */ 393} 394 395/* ARGSUSED */ 396int 397sys_gettimeofday(struct lwp *l, void *v, register_t *retval) 398{ 399 struct sys_gettimeofday_args /* { 400 syscallarg(struct timeval *) tp; 401 syscallarg(void *) tzp; really "struct timezone *" 402 } */ *uap = v; 403 struct timeval atv; 404 int error = 0; 405 struct timezone tzfake; 406 407 if (SCARG(uap, tp)) { 408 microtime(&atv); 409 error = copyout(&atv, SCARG(uap, tp), sizeof(atv)); 410 if (error) 411 return (error); 412 } 413 if (SCARG(uap, tzp)) { 414 /* 415 * NetBSD has no kernel notion of time zone, so we just 416 * fake up a timezone struct and return it if demanded. 417 */ 418 tzfake.tz_minuteswest = 0; 419 tzfake.tz_dsttime = 0; 420 error = copyout(&tzfake, SCARG(uap, tzp), sizeof(tzfake)); 421 } 422 return (error); 423} 424 425/* ARGSUSED */ 426int 427sys_settimeofday(struct lwp *l, void *v, register_t *retval) 428{ 429 struct sys_settimeofday_args /* { 430 syscallarg(const struct timeval *) tv; 431 syscallarg(const void *) tzp; really "const struct timezone *" 432 } */ *uap = v; 433 434 return settimeofday1(SCARG(uap, tv), true, SCARG(uap, tzp), l, true); 435} 436 437int 438settimeofday1(const struct timeval *utv, bool userspace, 439 const void *utzp, struct lwp *l, bool check_kauth) 440{ 441 struct timeval atv; 442 struct timespec ts; 443 int error; 444 445 /* Verify all parameters before changing time. */ 446 447 if (check_kauth) { 448 error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_TIME, 449 KAUTH_REQ_SYSTEM_TIME_SYSTEM, NULL, NULL, NULL); 450 if (error != 0) 451 return (error); 452 } 453 454 /* 455 * NetBSD has no kernel notion of time zone, and only an 456 * obsolete program would try to set it, so we log a warning. 457 */ 458 if (utzp) 459 log(LOG_WARNING, "pid %d attempted to set the " 460 "(obsolete) kernel time zone\n", l->l_proc->p_pid); 461 462 if (utv == NULL) 463 return 0; 464 465 if (userspace) { 466 if ((error = copyin(utv, &atv, sizeof(atv))) != 0) 467 return error; 468 utv = &atv; 469 } 470 471 TIMEVAL_TO_TIMESPEC(utv, &ts); 472 return settime(l->l_proc, &ts); 473} 474 475#ifndef __HAVE_TIMECOUNTER 476int tickdelta; /* current clock skew, us. per tick */ 477long timedelta; /* unapplied time correction, us. */ 478long bigadj = 1000000; /* use 10x skew above bigadj us. */ 479#endif 480 481int time_adjusted; /* set if an adjustment is made */ 482 483/* ARGSUSED */ 484int 485sys_adjtime(struct lwp *l, void *v, register_t *retval) 486{ 487 struct sys_adjtime_args /* { 488 syscallarg(const struct timeval *) delta; 489 syscallarg(struct timeval *) olddelta; 490 } */ *uap = v; 491 int error; 492 493 if ((error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_TIME, 494 KAUTH_REQ_SYSTEM_TIME_ADJTIME, NULL, NULL, NULL)) != 0) 495 return (error); 496 497 return adjtime1(SCARG(uap, delta), SCARG(uap, olddelta), l->l_proc); 498} 499 500int 501adjtime1(const struct timeval *delta, struct timeval *olddelta, struct proc *p) 502{ 503 struct timeval atv; 504 int error = 0; 505 506#ifdef __HAVE_TIMECOUNTER 507 extern int64_t time_adjtime; /* in kern_ntptime.c */ 508#else /* !__HAVE_TIMECOUNTER */ 509 long ndelta, ntickdelta, odelta; 510 int s; 511#endif /* !__HAVE_TIMECOUNTER */ 512 513#ifdef __HAVE_TIMECOUNTER 514 if (olddelta) { 515 atv.tv_sec = time_adjtime / 1000000; 516 atv.tv_usec = time_adjtime % 1000000; 517 if (atv.tv_usec < 0) { 518 atv.tv_usec += 1000000; 519 atv.tv_sec--; 520 } 521 error = copyout(&atv, olddelta, sizeof(struct timeval)); 522 if (error) 523 return (error); 524 } 525 526 if (delta) { 527 error = copyin(delta, &atv, sizeof(struct timeval)); 528 if (error) 529 return (error); 530 531 time_adjtime = (int64_t)atv.tv_sec * 1000000 + 532 atv.tv_usec; 533 534 if (time_adjtime) 535 /* We need to save the system time during shutdown */ 536 time_adjusted |= 1; 537 } 538#else /* !__HAVE_TIMECOUNTER */ 539 error = copyin(delta, &atv, sizeof(struct timeval)); 540 if (error) 541 return (error); 542 543 /* 544 * Compute the total correction and the rate at which to apply it. 545 * Round the adjustment down to a whole multiple of the per-tick 546 * delta, so that after some number of incremental changes in 547 * hardclock(), tickdelta will become zero, lest the correction 548 * overshoot and start taking us away from the desired final time. 549 */ 550 ndelta = atv.tv_sec * 1000000 + atv.tv_usec; 551 if (ndelta > bigadj || ndelta < -bigadj) 552 ntickdelta = 10 * tickadj; 553 else 554 ntickdelta = tickadj; 555 if (ndelta % ntickdelta) 556 ndelta = ndelta / ntickdelta * ntickdelta; 557 558 /* 559 * To make hardclock()'s job easier, make the per-tick delta negative 560 * if we want time to run slower; then hardclock can simply compute 561 * tick + tickdelta, and subtract tickdelta from timedelta. 562 */ 563 if (ndelta < 0) 564 ntickdelta = -ntickdelta; 565 if (ndelta != 0) 566 /* We need to save the system clock time during shutdown */ 567 time_adjusted |= 1; 568 s = splclock(); 569 odelta = timedelta; 570 timedelta = ndelta; 571 tickdelta = ntickdelta; 572 splx(s); 573 574 if (olddelta) { 575 atv.tv_sec = odelta / 1000000; 576 atv.tv_usec = odelta % 1000000; 577 error = copyout(&atv, olddelta, sizeof(struct timeval)); 578 } 579#endif /* __HAVE_TIMECOUNTER */ 580 581 return error; 582} 583 584/* 585 * Interval timer support. Both the BSD getitimer() family and the POSIX 586 * timer_*() family of routines are supported. 587 * 588 * All timers are kept in an array pointed to by p_timers, which is 589 * allocated on demand - many processes don't use timers at all. The 590 * first three elements in this array are reserved for the BSD timers: 591 * element 0 is ITIMER_REAL, element 1 is ITIMER_VIRTUAL, and element 592 * 2 is ITIMER_PROF. The rest may be allocated by the timer_create() 593 * syscall. 594 * 595 * Realtime timers are kept in the ptimer structure as an absolute 596 * time; virtual time timers are kept as a linked list of deltas. 597 * Virtual time timers are processed in the hardclock() routine of 598 * kern_clock.c. The real time timer is processed by a callout 599 * routine, called from the softclock() routine. Since a callout may 600 * be delayed in real time due to interrupt processing in the system, 601 * it is possible for the real time timeout routine (realtimeexpire, 602 * given below), to be delayed in real time past when it is supposed 603 * to occur. It does not suffice, therefore, to reload the real timer 604 * .it_value from the real time timers .it_interval. Rather, we 605 * compute the next time in absolute time the timer should go off. */ 606 607/* Allocate a POSIX realtime timer. */ 608int 609sys_timer_create(struct lwp *l, void *v, register_t *retval) 610{ 611 struct sys_timer_create_args /* { 612 syscallarg(clockid_t) clock_id; 613 syscallarg(struct sigevent *) evp; 614 syscallarg(timer_t *) timerid; 615 } */ *uap = v; 616 617 return timer_create1(SCARG(uap, timerid), SCARG(uap, clock_id), 618 SCARG(uap, evp), copyin, l); 619} 620 621int 622timer_create1(timer_t *tid, clockid_t id, struct sigevent *evp, 623 copyin_t fetch_event, struct lwp *l) 624{ 625 int error; 626 timer_t timerid; 627 struct ptimer *pt; 628 struct proc *p; 629 630 p = l->l_proc; 631 632 if (id < CLOCK_REALTIME || 633 id > CLOCK_PROF) 634 return (EINVAL); 635 636 if (p->p_timers == NULL) 637 timers_alloc(p); 638 639 /* Find a free timer slot, skipping those reserved for setitimer(). */ 640 for (timerid = 3; timerid < TIMER_MAX; timerid++) 641 if (p->p_timers->pts_timers[timerid] == NULL) 642 break; 643 644 if (timerid == TIMER_MAX) 645 return EAGAIN; 646 647 pt = pool_get(&ptimer_pool, PR_WAITOK); 648 if (evp) { 649 if (((error = 650 (*fetch_event)(evp, &pt->pt_ev, sizeof(pt->pt_ev))) != 0) || 651 ((pt->pt_ev.sigev_notify < SIGEV_NONE) || 652 (pt->pt_ev.sigev_notify > SIGEV_SA))) { 653 pool_put(&ptimer_pool, pt); 654 return (error ? error : EINVAL); 655 } 656 } else { 657 pt->pt_ev.sigev_notify = SIGEV_SIGNAL; 658 switch (id) { 659 case CLOCK_REALTIME: 660 pt->pt_ev.sigev_signo = SIGALRM; 661 break; 662 case CLOCK_VIRTUAL: 663 pt->pt_ev.sigev_signo = SIGVTALRM; 664 break; 665 case CLOCK_PROF: 666 pt->pt_ev.sigev_signo = SIGPROF; 667 break; 668 } 669 pt->pt_ev.sigev_value.sival_int = timerid; 670 } 671 pt->pt_info.ksi_signo = pt->pt_ev.sigev_signo; 672 pt->pt_info.ksi_errno = 0; 673 pt->pt_info.ksi_code = 0; 674 pt->pt_info.ksi_pid = p->p_pid; 675 pt->pt_info.ksi_uid = kauth_cred_getuid(l->l_cred); 676 pt->pt_info.ksi_value = pt->pt_ev.sigev_value; 677 678 pt->pt_type = id; 679 pt->pt_proc = p; 680 pt->pt_overruns = 0; 681 pt->pt_poverruns = 0; 682 pt->pt_entry = timerid; 683 timerclear(&pt->pt_time.it_value); 684 if (id == CLOCK_REALTIME) 685 callout_init(&pt->pt_ch, 0); 686 else 687 pt->pt_active = 0; 688 689 p->p_timers->pts_timers[timerid] = pt; 690 691 return copyout(&timerid, tid, sizeof(timerid)); 692} 693 694/* Delete a POSIX realtime timer */ 695int 696sys_timer_delete(struct lwp *l, void *v, register_t *retval) 697{ 698 struct sys_timer_delete_args /* { 699 syscallarg(timer_t) timerid; 700 } */ *uap = v; 701 struct proc *p = l->l_proc; 702 timer_t timerid; 703 struct ptimer *pt, *ptn; 704 int s; 705 706 timerid = SCARG(uap, timerid); 707 708 if ((p->p_timers == NULL) || 709 (timerid < 2) || (timerid >= TIMER_MAX) || 710 ((pt = p->p_timers->pts_timers[timerid]) == NULL)) 711 return (EINVAL); 712 713 if (pt->pt_type == CLOCK_REALTIME) { 714 callout_stop(&pt->pt_ch); 715 callout_destroy(&pt->pt_ch); 716 } else if (pt->pt_active) { 717 s = splclock(); 718 ptn = LIST_NEXT(pt, pt_list); 719 LIST_REMOVE(pt, pt_list); 720 for ( ; ptn; ptn = LIST_NEXT(ptn, pt_list)) 721 timeradd(&pt->pt_time.it_value, &ptn->pt_time.it_value, 722 &ptn->pt_time.it_value); 723 splx(s); 724 } 725 726 p->p_timers->pts_timers[timerid] = NULL; 727 pool_put(&ptimer_pool, pt); 728 729 return (0); 730} 731 732/* 733 * Set up the given timer. The value in pt->pt_time.it_value is taken 734 * to be an absolute time for CLOCK_REALTIME timers and a relative 735 * time for virtual timers. 736 * Must be called at splclock(). 737 */ 738void 739timer_settime(struct ptimer *pt) 740{ 741 struct ptimer *ptn, *pptn; 742 struct ptlist *ptl; 743 744 if (pt->pt_type == CLOCK_REALTIME) { 745 callout_stop(&pt->pt_ch); 746 if (timerisset(&pt->pt_time.it_value)) { 747 /* 748 * Don't need to check hzto() return value, here. 749 * callout_reset() does it for us. 750 */ 751 callout_reset(&pt->pt_ch, hzto(&pt->pt_time.it_value), 752 realtimerexpire, pt); 753 } 754 } else { 755 if (pt->pt_active) { 756 ptn = LIST_NEXT(pt, pt_list); 757 LIST_REMOVE(pt, pt_list); 758 for ( ; ptn; ptn = LIST_NEXT(ptn, pt_list)) 759 timeradd(&pt->pt_time.it_value, 760 &ptn->pt_time.it_value, 761 &ptn->pt_time.it_value); 762 } 763 if (timerisset(&pt->pt_time.it_value)) { 764 if (pt->pt_type == CLOCK_VIRTUAL) 765 ptl = &pt->pt_proc->p_timers->pts_virtual; 766 else 767 ptl = &pt->pt_proc->p_timers->pts_prof; 768 769 for (ptn = LIST_FIRST(ptl), pptn = NULL; 770 ptn && timercmp(&pt->pt_time.it_value, 771 &ptn->pt_time.it_value, >); 772 pptn = ptn, ptn = LIST_NEXT(ptn, pt_list)) 773 timersub(&pt->pt_time.it_value, 774 &ptn->pt_time.it_value, 775 &pt->pt_time.it_value); 776 777 if (pptn) 778 LIST_INSERT_AFTER(pptn, pt, pt_list); 779 else 780 LIST_INSERT_HEAD(ptl, pt, pt_list); 781 782 for ( ; ptn ; ptn = LIST_NEXT(ptn, pt_list)) 783 timersub(&ptn->pt_time.it_value, 784 &pt->pt_time.it_value, 785 &ptn->pt_time.it_value); 786 787 pt->pt_active = 1; 788 } else 789 pt->pt_active = 0; 790 } 791} 792 793void 794timer_gettime(struct ptimer *pt, struct itimerval *aitv) 795{ 796#ifdef __HAVE_TIMECOUNTER 797 struct timeval now; 798#endif 799 struct ptimer *ptn; 800 801 *aitv = pt->pt_time; 802 if (pt->pt_type == CLOCK_REALTIME) { 803 /* 804 * Convert from absolute to relative time in .it_value 805 * part of real time timer. If time for real time 806 * timer has passed return 0, else return difference 807 * between current time and time for the timer to go 808 * off. 809 */ 810 if (timerisset(&aitv->it_value)) { 811#ifdef __HAVE_TIMECOUNTER 812 getmicrotime(&now); 813 if (timercmp(&aitv->it_value, &now, <)) 814 timerclear(&aitv->it_value); 815 else 816 timersub(&aitv->it_value, &now, 817 &aitv->it_value); 818#else /* !__HAVE_TIMECOUNTER */ 819 if (timercmp(&aitv->it_value, &time, <)) 820 timerclear(&aitv->it_value); 821 else 822 timersub(&aitv->it_value, &time, 823 &aitv->it_value); 824#endif /* !__HAVE_TIMECOUNTER */ 825 } 826 } else if (pt->pt_active) { 827 if (pt->pt_type == CLOCK_VIRTUAL) 828 ptn = LIST_FIRST(&pt->pt_proc->p_timers->pts_virtual); 829 else 830 ptn = LIST_FIRST(&pt->pt_proc->p_timers->pts_prof); 831 for ( ; ptn && ptn != pt; ptn = LIST_NEXT(ptn, pt_list)) 832 timeradd(&aitv->it_value, 833 &ptn->pt_time.it_value, &aitv->it_value); 834 KASSERT(ptn != NULL); /* pt should be findable on the list */ 835 } else 836 timerclear(&aitv->it_value); 837} 838 839 840 841/* Set and arm a POSIX realtime timer */ 842int 843sys_timer_settime(struct lwp *l, void *v, register_t *retval) 844{ 845 struct sys_timer_settime_args /* { 846 syscallarg(timer_t) timerid; 847 syscallarg(int) flags; 848 syscallarg(const struct itimerspec *) value; 849 syscallarg(struct itimerspec *) ovalue; 850 } */ *uap = v; 851 int error; 852 struct itimerspec value, ovalue, *ovp = NULL; 853 854 if ((error = copyin(SCARG(uap, value), &value, 855 sizeof(struct itimerspec))) != 0) 856 return (error); 857 858 if (SCARG(uap, ovalue)) 859 ovp = &ovalue; 860 861 if ((error = dotimer_settime(SCARG(uap, timerid), &value, ovp, 862 SCARG(uap, flags), l->l_proc)) != 0) 863 return error; 864 865 if (ovp) 866 return copyout(&ovalue, SCARG(uap, ovalue), 867 sizeof(struct itimerspec)); 868 return 0; 869} 870 871int 872dotimer_settime(int timerid, struct itimerspec *value, 873 struct itimerspec *ovalue, int flags, struct proc *p) 874{ 875#ifdef __HAVE_TIMECOUNTER 876 struct timeval now; 877#endif 878 struct itimerval val, oval; 879 struct ptimer *pt; 880 int s; 881 882 if ((p->p_timers == NULL) || 883 (timerid < 2) || (timerid >= TIMER_MAX) || 884 ((pt = p->p_timers->pts_timers[timerid]) == NULL)) 885 return (EINVAL); 886 887 TIMESPEC_TO_TIMEVAL(&val.it_value, &value->it_value); 888 TIMESPEC_TO_TIMEVAL(&val.it_interval, &value->it_interval); 889 if (itimerfix(&val.it_value) || itimerfix(&val.it_interval)) 890 return (EINVAL); 891 892 oval = pt->pt_time; 893 pt->pt_time = val; 894 895 s = splclock(); 896 /* 897 * If we've been passed a relative time for a realtime timer, 898 * convert it to absolute; if an absolute time for a virtual 899 * timer, convert it to relative and make sure we don't set it 900 * to zero, which would cancel the timer, or let it go 901 * negative, which would confuse the comparison tests. 902 */ 903 if (timerisset(&pt->pt_time.it_value)) { 904 if (pt->pt_type == CLOCK_REALTIME) { 905#ifdef __HAVE_TIMECOUNTER 906 if ((flags & TIMER_ABSTIME) == 0) { 907 getmicrotime(&now); 908 timeradd(&pt->pt_time.it_value, &now, 909 &pt->pt_time.it_value); 910 } 911#else /* !__HAVE_TIMECOUNTER */ 912 if ((flags & TIMER_ABSTIME) == 0) 913 timeradd(&pt->pt_time.it_value, &time, 914 &pt->pt_time.it_value); 915#endif /* !__HAVE_TIMECOUNTER */ 916 } else { 917 if ((flags & TIMER_ABSTIME) != 0) { 918#ifdef __HAVE_TIMECOUNTER 919 getmicrotime(&now); 920 timersub(&pt->pt_time.it_value, &now, 921 &pt->pt_time.it_value); 922#else /* !__HAVE_TIMECOUNTER */ 923 timersub(&pt->pt_time.it_value, &time, 924 &pt->pt_time.it_value); 925#endif /* !__HAVE_TIMECOUNTER */ 926 if (!timerisset(&pt->pt_time.it_value) || 927 pt->pt_time.it_value.tv_sec < 0) { 928 pt->pt_time.it_value.tv_sec = 0; 929 pt->pt_time.it_value.tv_usec = 1; 930 } 931 } 932 } 933 } 934 935 timer_settime(pt); 936 splx(s); 937 938 if (ovalue) { 939 TIMEVAL_TO_TIMESPEC(&oval.it_value, &ovalue->it_value); 940 TIMEVAL_TO_TIMESPEC(&oval.it_interval, &ovalue->it_interval); 941 } 942 943 return (0); 944} 945 946/* Return the time remaining until a POSIX timer fires. */ 947int 948sys_timer_gettime(struct lwp *l, void *v, register_t *retval) 949{ 950 struct sys_timer_gettime_args /* { 951 syscallarg(timer_t) timerid; 952 syscallarg(struct itimerspec *) value; 953 } */ *uap = v; 954 struct itimerspec its; 955 int error; 956 957 if ((error = dotimer_gettime(SCARG(uap, timerid), l->l_proc, 958 &its)) != 0) 959 return error; 960 961 return copyout(&its, SCARG(uap, value), sizeof(its)); 962} 963 964int 965dotimer_gettime(int timerid, struct proc *p, struct itimerspec *its) 966{ 967 int s; 968 struct ptimer *pt; 969 struct itimerval aitv; 970 971 if ((p->p_timers == NULL) || 972 (timerid < 2) || (timerid >= TIMER_MAX) || 973 ((pt = p->p_timers->pts_timers[timerid]) == NULL)) 974 return (EINVAL); 975 976 s = splclock(); 977 timer_gettime(pt, &aitv); 978 splx(s); 979 980 TIMEVAL_TO_TIMESPEC(&aitv.it_interval, &its->it_interval); 981 TIMEVAL_TO_TIMESPEC(&aitv.it_value, &its->it_value); 982 983 return 0; 984} 985 986/* 987 * Return the count of the number of times a periodic timer expired 988 * while a notification was already pending. The counter is reset when 989 * a timer expires and a notification can be posted. 990 */ 991int 992sys_timer_getoverrun(struct lwp *l, void *v, register_t *retval) 993{ 994 struct sys_timer_getoverrun_args /* { 995 syscallarg(timer_t) timerid; 996 } */ *uap = v; 997 struct proc *p = l->l_proc; 998 int timerid; 999 struct ptimer *pt; 1000 1001 timerid = SCARG(uap, timerid); 1002 1003 if ((p->p_timers == NULL) || 1004 (timerid < 2) || (timerid >= TIMER_MAX) || 1005 ((pt = p->p_timers->pts_timers[timerid]) == NULL)) 1006 return (EINVAL); 1007 1008 *retval = pt->pt_poverruns; 1009 1010 return (0); 1011} 1012 1013/* 1014 * Real interval timer expired: 1015 * send process whose timer expired an alarm signal. 1016 * If time is not set up to reload, then just return. 1017 * Else compute next time timer should go off which is > current time. 1018 * This is where delay in processing this timeout causes multiple 1019 * SIGALRM calls to be compressed into one. 1020 */ 1021void 1022realtimerexpire(void *arg) 1023{ 1024#ifdef __HAVE_TIMECOUNTER 1025 struct timeval now; 1026#endif 1027 struct ptimer *pt; 1028 int s; 1029 1030 pt = (struct ptimer *)arg; 1031 1032 itimerfire(pt); 1033 1034 if (!timerisset(&pt->pt_time.it_interval)) { 1035 timerclear(&pt->pt_time.it_value); 1036 return; 1037 } 1038#ifdef __HAVE_TIMECOUNTER 1039 for (;;) { 1040 s = splclock(); /* XXX need spl now? */ 1041 timeradd(&pt->pt_time.it_value, 1042 &pt->pt_time.it_interval, &pt->pt_time.it_value); 1043 getmicrotime(&now); 1044 if (timercmp(&pt->pt_time.it_value, &now, >)) { 1045 /* 1046 * Don't need to check hzto() return value, here. 1047 * callout_reset() does it for us. 1048 */ 1049 callout_reset(&pt->pt_ch, hzto(&pt->pt_time.it_value), 1050 realtimerexpire, pt); 1051 splx(s); 1052 return; 1053 } 1054 splx(s); 1055 pt->pt_overruns++; 1056 } 1057#else /* !__HAVE_TIMECOUNTER */ 1058 for (;;) { 1059 s = splclock(); 1060 timeradd(&pt->pt_time.it_value, 1061 &pt->pt_time.it_interval, &pt->pt_time.it_value); 1062 if (timercmp(&pt->pt_time.it_value, &time, >)) { 1063 /* 1064 * Don't need to check hzto() return value, here. 1065 * callout_reset() does it for us. 1066 */ 1067 callout_reset(&pt->pt_ch, hzto(&pt->pt_time.it_value), 1068 realtimerexpire, pt); 1069 splx(s); 1070 return; 1071 } 1072 splx(s); 1073 pt->pt_overruns++; 1074 } 1075#endif /* !__HAVE_TIMECOUNTER */ 1076} 1077 1078/* BSD routine to get the value of an interval timer. */ 1079/* ARGSUSED */ 1080int 1081sys_getitimer(struct lwp *l, void *v, register_t *retval) 1082{ 1083 struct sys_getitimer_args /* { 1084 syscallarg(int) which; 1085 syscallarg(struct itimerval *) itv; 1086 } */ *uap = v; 1087 struct proc *p = l->l_proc; 1088 struct itimerval aitv; 1089 int error; 1090 1091 error = dogetitimer(p, SCARG(uap, which), &aitv); 1092 if (error) 1093 return error; 1094 return (copyout(&aitv, SCARG(uap, itv), sizeof(struct itimerval))); 1095} 1096 1097int 1098dogetitimer(struct proc *p, int which, struct itimerval *itvp) 1099{ 1100 int s; 1101 1102 if ((u_int)which > ITIMER_PROF) 1103 return (EINVAL); 1104 1105 if ((p->p_timers == NULL) || (p->p_timers->pts_timers[which] == NULL)){ 1106 timerclear(&itvp->it_value); 1107 timerclear(&itvp->it_interval); 1108 } else { 1109 s = splclock(); 1110 timer_gettime(p->p_timers->pts_timers[which], itvp); 1111 splx(s); 1112 } 1113 1114 return 0; 1115} 1116 1117/* BSD routine to set/arm an interval timer. */ 1118/* ARGSUSED */ 1119int 1120sys_setitimer(struct lwp *l, void *v, register_t *retval) 1121{ 1122 struct sys_setitimer_args /* { 1123 syscallarg(int) which; 1124 syscallarg(const struct itimerval *) itv; 1125 syscallarg(struct itimerval *) oitv; 1126 } */ *uap = v; 1127 struct proc *p = l->l_proc; 1128 int which = SCARG(uap, which); 1129 struct sys_getitimer_args getargs; 1130 const struct itimerval *itvp; 1131 struct itimerval aitv; 1132 int error; 1133 1134 if ((u_int)which > ITIMER_PROF) 1135 return (EINVAL); 1136 itvp = SCARG(uap, itv); 1137 if (itvp && 1138 (error = copyin(itvp, &aitv, sizeof(struct itimerval)) != 0)) 1139 return (error); 1140 if (SCARG(uap, oitv) != NULL) { 1141 SCARG(&getargs, which) = which; 1142 SCARG(&getargs, itv) = SCARG(uap, oitv); 1143 if ((error = sys_getitimer(l, &getargs, retval)) != 0) 1144 return (error); 1145 } 1146 if (itvp == 0) 1147 return (0); 1148 1149 return dosetitimer(p, which, &aitv); 1150} 1151 1152int 1153dosetitimer(struct proc *p, int which, struct itimerval *itvp) 1154{ 1155#ifdef __HAVE_TIMECOUNTER 1156 struct timeval now; 1157#endif 1158 struct ptimer *pt; 1159 int s; 1160 1161 if (itimerfix(&itvp->it_value) || itimerfix(&itvp->it_interval)) 1162 return (EINVAL); 1163 1164 /* 1165 * Don't bother allocating data structures if the process just 1166 * wants to clear the timer. 1167 */ 1168 if (!timerisset(&itvp->it_value) && 1169 ((p->p_timers == NULL) ||(p->p_timers->pts_timers[which] == NULL))) 1170 return (0); 1171 1172 if (p->p_timers == NULL) 1173 timers_alloc(p); 1174 if (p->p_timers->pts_timers[which] == NULL) { 1175 pt = pool_get(&ptimer_pool, PR_WAITOK); 1176 pt->pt_ev.sigev_notify = SIGEV_SIGNAL; 1177 pt->pt_ev.sigev_value.sival_int = which; 1178 pt->pt_overruns = 0; 1179 pt->pt_proc = p; 1180 pt->pt_type = which; 1181 pt->pt_entry = which; 1182 switch (which) { 1183 case ITIMER_REAL: 1184 callout_init(&pt->pt_ch, 0); 1185 pt->pt_ev.sigev_signo = SIGALRM; 1186 break; 1187 case ITIMER_VIRTUAL: 1188 pt->pt_active = 0; 1189 pt->pt_ev.sigev_signo = SIGVTALRM; 1190 break; 1191 case ITIMER_PROF: 1192 pt->pt_active = 0; 1193 pt->pt_ev.sigev_signo = SIGPROF; 1194 break; 1195 } 1196 } else 1197 pt = p->p_timers->pts_timers[which]; 1198 1199 pt->pt_time = *itvp; 1200 p->p_timers->pts_timers[which] = pt; 1201 1202 s = splclock(); 1203 if ((which == ITIMER_REAL) && timerisset(&pt->pt_time.it_value)) { 1204 /* Convert to absolute time */ 1205#ifdef __HAVE_TIMECOUNTER 1206 /* XXX need to wrap in splclock for timecounters case? */ 1207 getmicrotime(&now); 1208 timeradd(&pt->pt_time.it_value, &now, &pt->pt_time.it_value); 1209#else /* !__HAVE_TIMECOUNTER */ 1210 timeradd(&pt->pt_time.it_value, &time, &pt->pt_time.it_value); 1211#endif /* !__HAVE_TIMECOUNTER */ 1212 } 1213 timer_settime(pt); 1214 splx(s); 1215 1216 return (0); 1217} 1218 1219/* Utility routines to manage the array of pointers to timers. */ 1220void 1221timers_alloc(struct proc *p) 1222{ 1223 int i; 1224 struct ptimers *pts; 1225 1226 pts = pool_get(&ptimers_pool, PR_WAITOK); 1227 LIST_INIT(&pts->pts_virtual); 1228 LIST_INIT(&pts->pts_prof); 1229 for (i = 0; i < TIMER_MAX; i++) 1230 pts->pts_timers[i] = NULL; 1231 pts->pts_fired = 0; 1232 p->p_timers = pts; 1233} 1234 1235/* 1236 * Clean up the per-process timers. If "which" is set to TIMERS_ALL, 1237 * then clean up all timers and free all the data structures. If 1238 * "which" is set to TIMERS_POSIX, only clean up the timers allocated 1239 * by timer_create(), not the BSD setitimer() timers, and only free the 1240 * structure if none of those remain. 1241 */ 1242void 1243timers_free(struct proc *p, int which) 1244{ 1245 int i, s; 1246 struct ptimers *pts; 1247 struct ptimer *pt, *ptn; 1248 struct timeval tv; 1249 1250 if (p->p_timers) { 1251 pts = p->p_timers; 1252 if (which == TIMERS_ALL) 1253 i = 0; 1254 else { 1255 s = splclock(); 1256 timerclear(&tv); 1257 for (ptn = LIST_FIRST(&p->p_timers->pts_virtual); 1258 ptn && ptn != pts->pts_timers[ITIMER_VIRTUAL]; 1259 ptn = LIST_NEXT(ptn, pt_list)) 1260 timeradd(&tv, &ptn->pt_time.it_value, &tv); 1261 LIST_FIRST(&p->p_timers->pts_virtual) = NULL; 1262 if (ptn) { 1263 timeradd(&tv, &ptn->pt_time.it_value, 1264 &ptn->pt_time.it_value); 1265 LIST_INSERT_HEAD(&p->p_timers->pts_virtual, 1266 ptn, pt_list); 1267 } 1268 1269 timerclear(&tv); 1270 for (ptn = LIST_FIRST(&p->p_timers->pts_prof); 1271 ptn && ptn != pts->pts_timers[ITIMER_PROF]; 1272 ptn = LIST_NEXT(ptn, pt_list)) 1273 timeradd(&tv, &ptn->pt_time.it_value, &tv); 1274 LIST_FIRST(&p->p_timers->pts_prof) = NULL; 1275 if (ptn) { 1276 timeradd(&tv, &ptn->pt_time.it_value, 1277 &ptn->pt_time.it_value); 1278 LIST_INSERT_HEAD(&p->p_timers->pts_prof, ptn, 1279 pt_list); 1280 } 1281 splx(s); 1282 i = 3; 1283 } 1284 for ( ; i < TIMER_MAX; i++) 1285 if ((pt = pts->pts_timers[i]) != NULL) { 1286 if (pt->pt_type == CLOCK_REALTIME) { 1287 callout_stop(&pt->pt_ch); 1288 callout_destroy(&pt->pt_ch); 1289 } 1290 pts->pts_timers[i] = NULL; 1291 pool_put(&ptimer_pool, pt); 1292 } 1293 if ((pts->pts_timers[0] == NULL) && 1294 (pts->pts_timers[1] == NULL) && 1295 (pts->pts_timers[2] == NULL)) { 1296 p->p_timers = NULL; 1297 pool_put(&ptimers_pool, pts); 1298 } 1299 } 1300} 1301 1302/* 1303 * Decrement an interval timer by a specified number 1304 * of microseconds, which must be less than a second, 1305 * i.e. < 1000000. If the timer expires, then reload 1306 * it. In this case, carry over (usec - old value) to 1307 * reduce the value reloaded into the timer so that 1308 * the timer does not drift. This routine assumes 1309 * that it is called in a context where the timers 1310 * on which it is operating cannot change in value. 1311 */ 1312int 1313itimerdecr(struct ptimer *pt, int usec) 1314{ 1315 struct itimerval *itp; 1316 1317 itp = &pt->pt_time; 1318 if (itp->it_value.tv_usec < usec) { 1319 if (itp->it_value.tv_sec == 0) { 1320 /* expired, and already in next interval */ 1321 usec -= itp->it_value.tv_usec; 1322 goto expire; 1323 } 1324 itp->it_value.tv_usec += 1000000; 1325 itp->it_value.tv_sec--; 1326 } 1327 itp->it_value.tv_usec -= usec; 1328 usec = 0; 1329 if (timerisset(&itp->it_value)) 1330 return (1); 1331 /* expired, exactly at end of interval */ 1332expire: 1333 if (timerisset(&itp->it_interval)) { 1334 itp->it_value = itp->it_interval; 1335 itp->it_value.tv_usec -= usec; 1336 if (itp->it_value.tv_usec < 0) { 1337 itp->it_value.tv_usec += 1000000; 1338 itp->it_value.tv_sec--; 1339 } 1340 timer_settime(pt); 1341 } else 1342 itp->it_value.tv_usec = 0; /* sec is already 0 */ 1343 return (0); 1344} 1345 1346void 1347itimerfire(struct ptimer *pt) 1348{ 1349 struct proc *p = pt->pt_proc; 1350 1351 if (pt->pt_ev.sigev_notify == SIGEV_SIGNAL) { 1352 /* 1353 * No RT signal infrastructure exists at this time; 1354 * just post the signal number and throw away the 1355 * value. 1356 */ 1357 if (sigismember(&p->p_sigpend.sp_set, pt->pt_ev.sigev_signo)) 1358 pt->pt_overruns++; 1359 else { 1360 ksiginfo_t ksi; 1361 KSI_INIT(&ksi); 1362 ksi.ksi_signo = pt->pt_ev.sigev_signo; 1363 ksi.ksi_code = SI_TIMER; 1364 ksi.ksi_value = pt->pt_ev.sigev_value; 1365 pt->pt_poverruns = pt->pt_overruns; 1366 pt->pt_overruns = 0; 1367 mutex_enter(&proclist_mutex); 1368 kpsignal(p, &ksi, NULL); 1369 mutex_exit(&proclist_mutex); 1370 } 1371 } 1372} 1373 1374/* 1375 * ratecheck(): simple time-based rate-limit checking. see ratecheck(9) 1376 * for usage and rationale. 1377 */ 1378int 1379ratecheck(struct timeval *lasttime, const struct timeval *mininterval) 1380{ 1381 struct timeval tv, delta; 1382 int rv = 0; 1383#ifndef __HAVE_TIMECOUNTER 1384 int s; 1385#endif 1386 1387#ifdef __HAVE_TIMECOUNTER 1388 getmicrouptime(&tv); 1389#else /* !__HAVE_TIMECOUNTER */ 1390 s = splclock(); 1391 tv = mono_time; 1392 splx(s); 1393#endif /* !__HAVE_TIMECOUNTER */ 1394 timersub(&tv, lasttime, &delta); 1395 1396 /* 1397 * check for 0,0 is so that the message will be seen at least once, 1398 * even if interval is huge. 1399 */ 1400 if (timercmp(&delta, mininterval, >=) || 1401 (lasttime->tv_sec == 0 && lasttime->tv_usec == 0)) { 1402 *lasttime = tv; 1403 rv = 1; 1404 } 1405 1406 return (rv); 1407} 1408 1409/* 1410 * ppsratecheck(): packets (or events) per second limitation. 1411 */ 1412int 1413ppsratecheck(struct timeval *lasttime, int *curpps, int maxpps) 1414{ 1415 struct timeval tv, delta; 1416 int rv; 1417#ifndef __HAVE_TIMECOUNTER 1418 int s; 1419#endif 1420 1421#ifdef __HAVE_TIMECOUNTER 1422 getmicrouptime(&tv); 1423#else /* !__HAVE_TIMECOUNTER */ 1424 s = splclock(); 1425 tv = mono_time; 1426 splx(s); 1427#endif /* !__HAVE_TIMECOUNTER */ 1428 timersub(&tv, lasttime, &delta); 1429 1430 /* 1431 * check for 0,0 is so that the message will be seen at least once. 1432 * if more than one second have passed since the last update of 1433 * lasttime, reset the counter. 1434 * 1435 * we do increment *curpps even in *curpps < maxpps case, as some may 1436 * try to use *curpps for stat purposes as well. 1437 */ 1438 if ((lasttime->tv_sec == 0 && lasttime->tv_usec == 0) || 1439 delta.tv_sec >= 1) { 1440 *lasttime = tv; 1441 *curpps = 0; 1442 } 1443 if (maxpps < 0) 1444 rv = 1; 1445 else if (*curpps < maxpps) 1446 rv = 1; 1447 else 1448 rv = 0; 1449 1450#if 1 /*DIAGNOSTIC?*/ 1451 /* be careful about wrap-around */ 1452 if (*curpps + 1 > *curpps) 1453 *curpps = *curpps + 1; 1454#else 1455 /* 1456 * assume that there's not too many calls to this function. 1457 * not sure if the assumption holds, as it depends on *caller's* 1458 * behavior, not the behavior of this function. 1459 * IMHO it is wrong to make assumption on the caller's behavior, 1460 * so the above #if is #if 1, not #ifdef DIAGNOSTIC. 1461 */ 1462 *curpps = *curpps + 1; 1463#endif 1464 1465 return (rv); 1466} 1467