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