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
94 POOL_INIT(ptimer_pool, sizeof(struct ptimer), 0, 0, 0, "ptimerpl",
95 &pool_allocator_nointr, IPL_NONE);
96 POOL_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 */
109 int
110 settime(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 */
198 int
199 sys_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 */
224 int
225 sys_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
241 int
242 clock_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
264 int
265 sys_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 */
296 int
297 sys_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
318 int
319 nanosleep1(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 */
396 int
397 sys_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 */
426 int
427 sys_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
437 int
438 settimeofday1(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
476 int tickdelta; /* current clock skew, us. per tick */
477 long timedelta; /* unapplied time correction, us. */
478 long bigadj = 1000000; /* use 10x skew above bigadj us. */
479 #endif
480
481 int time_adjusted; /* set if an adjustment is made */
482
483 /* ARGSUSED */
484 int
485 sys_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
500 int
501 adjtime1(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. */
608 int
609 sys_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
621 int
622 timer_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 */
695 int
696 sys_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 */
738 void
739 timer_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
793 void
794 timer_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 */
842 int
843 sys_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
871 int
872 dotimer_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. */
947 int
948 sys_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
964 int
965 dotimer_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 */
991 int
992 sys_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 */
1021 void
1022 realtimerexpire(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 */
1080 int
1081 sys_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
1097 int
1098 dogetitimer(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 */
1119 int
1120 sys_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
1152 int
1153 dosetitimer(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. */
1220 void
1221 timers_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 */
1242 void
1243 timers_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 */
1312 int
1313 itimerdecr(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 */
1332 expire:
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
1346 void
1347 itimerfire(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 */
1378 int
1379 ratecheck(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 */
1412 int
1413 ppsratecheck(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