Home | History | Annotate | Line # | Download | only in kern
kern_time.c revision 1.54.2.5
      1 /*	$NetBSD: kern_time.c,v 1.54.2.5 2001/11/17 01:13:51 nathanw Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2000 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. All advertising materials mentioning features or use of this software
     52  *    must display the following acknowledgement:
     53  *	This product includes software developed by the University of
     54  *	California, Berkeley and its contributors.
     55  * 4. Neither the name of the University nor the names of its contributors
     56  *    may be used to endorse or promote products derived from this software
     57  *    without specific prior written permission.
     58  *
     59  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     60  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     61  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     62  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     63  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     64  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     65  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     66  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     67  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     68  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     69  * SUCH DAMAGE.
     70  *
     71  *	@(#)kern_time.c	8.4 (Berkeley) 5/26/95
     72  */
     73 
     74 #include <sys/cdefs.h>
     75 __KERNEL_RCSID(0, "$NetBSD: kern_time.c,v 1.54.2.5 2001/11/17 01:13:51 nathanw Exp $");
     76 
     77 #include "fs_nfs.h"
     78 #include "opt_nfs.h"
     79 #include "opt_nfsserver.h"
     80 
     81 #include <sys/param.h>
     82 #include <sys/resourcevar.h>
     83 #include <sys/kernel.h>
     84 #include <sys/systm.h>
     85 #include <sys/lwp.h>
     86 #include <sys/malloc.h>
     87 #include <sys/proc.h>
     88 #include <sys/sa.h>
     89 #include <sys/savar.h>
     90 #include <sys/vnode.h>
     91 #include <sys/signalvar.h>
     92 #include <sys/syslog.h>
     93 
     94 #include <sys/mount.h>
     95 #include <sys/syscallargs.h>
     96 
     97 #include <uvm/uvm_extern.h>
     98 
     99 #if defined(NFS) || defined(NFSSERVER)
    100 #include <nfs/rpcv2.h>
    101 #include <nfs/nfsproto.h>
    102 #include <nfs/nfs_var.h>
    103 #endif
    104 
    105 #include <machine/cpu.h>
    106 
    107 static void realtimerupcall(struct lwp *, void *);
    108 
    109 
    110 /* Time of day and interval timer support.
    111  *
    112  * These routines provide the kernel entry points to get and set
    113  * the time-of-day and per-process interval timers.  Subroutines
    114  * here provide support for adding and subtracting timeval structures
    115  * and decrementing interval timers, optionally reloading the interval
    116  * timers when they expire.
    117  */
    118 
    119 /* This function is used by clock_settime and settimeofday */
    120 int
    121 settime(struct timeval *tv)
    122 {
    123 	struct timeval delta;
    124 	struct cpu_info *ci;
    125 	int s;
    126 
    127 	/* WHAT DO WE DO ABOUT PENDING REAL-TIME TIMEOUTS??? */
    128 	s = splclock();
    129 	timersub(tv, &time, &delta);
    130 	if ((delta.tv_sec < 0 || delta.tv_usec < 0) && securelevel > 1) {
    131 		splx(s);
    132 		return (EPERM);
    133 	}
    134 #ifdef notyet
    135 	if ((delta.tv_sec < 86400) && securelevel > 0) {
    136 		splx(s);
    137 		return (EPERM);
    138 	}
    139 #endif
    140 	time = *tv;
    141 	(void) spllowersoftclock();
    142 	timeradd(&boottime, &delta, &boottime);
    143 	/*
    144 	 * XXXSMP
    145 	 * This is wrong.  We should traverse a list of all
    146 	 * CPUs and add the delta to the runtime of those
    147 	 * CPUs which have a process on them.
    148 	 */
    149 	ci = curcpu();
    150 	timeradd(&ci->ci_schedstate.spc_runtime, &delta,
    151 	    &ci->ci_schedstate.spc_runtime);
    152 #	if (defined(NFS) && !defined (NFS_V2_ONLY)) || defined(NFSSERVER)
    153 		nqnfs_lease_updatetime(delta.tv_sec);
    154 #	endif
    155 	splx(s);
    156 	resettodr();
    157 	return (0);
    158 }
    159 
    160 /* ARGSUSED */
    161 int
    162 sys_clock_gettime(struct lwp *l, void *v, register_t *retval)
    163 {
    164 	struct sys_clock_gettime_args /* {
    165 		syscallarg(clockid_t) clock_id;
    166 		syscallarg(struct timespec *) tp;
    167 	} */ *uap = v;
    168 	clockid_t clock_id;
    169 	struct timeval atv;
    170 	struct timespec ats;
    171 
    172 	clock_id = SCARG(uap, clock_id);
    173 	if (clock_id != CLOCK_REALTIME)
    174 		return (EINVAL);
    175 
    176 	microtime(&atv);
    177 	TIMEVAL_TO_TIMESPEC(&atv,&ats);
    178 
    179 	return copyout(&ats, SCARG(uap, tp), sizeof(ats));
    180 }
    181 
    182 /* ARGSUSED */
    183 int
    184 sys_clock_settime(l, v, retval)
    185 	struct lwp *l;
    186 	void *v;
    187 	register_t *retval;
    188 {
    189 	struct sys_clock_settime_args /* {
    190 		syscallarg(clockid_t) clock_id;
    191 		syscallarg(const struct timespec *) tp;
    192 	} */ *uap = v;
    193 	struct proc *p = l->l_proc;
    194 	clockid_t clock_id;
    195 	struct timespec ats;
    196 	int error;
    197 
    198 	if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
    199 		return (error);
    200 
    201 	clock_id = SCARG(uap, clock_id);
    202 
    203 	if ((error = copyin(SCARG(uap, tp), &ats, sizeof(ats))) != 0)
    204 		return (error);
    205 
    206 	return (clock_settime1(clock_id, &ats));
    207 }
    208 
    209 
    210 int
    211 clock_settime1(clockid_t clock_id, struct timespec *ats)
    212 {
    213 	struct timeval atv;
    214 	int error;
    215 
    216 	if (clock_id != CLOCK_REALTIME)
    217 		return (EINVAL);
    218 
    219 	TIMESPEC_TO_TIMEVAL(&atv, ats);
    220 	if ((error = settime(&atv)) != 0)
    221 		return (error);
    222 
    223 	return 0;
    224 }
    225 
    226 int
    227 sys_clock_getres(struct lwp *l, void *v, register_t *retval)
    228 {
    229 	struct sys_clock_getres_args /* {
    230 		syscallarg(clockid_t) clock_id;
    231 		syscallarg(struct timespec *) tp;
    232 	} */ *uap = v;
    233 	clockid_t clock_id;
    234 	struct timespec ts;
    235 	int error = 0;
    236 
    237 	clock_id = SCARG(uap, clock_id);
    238 	if (clock_id != CLOCK_REALTIME)
    239 		return (EINVAL);
    240 
    241 	if (SCARG(uap, tp)) {
    242 		ts.tv_sec = 0;
    243 		ts.tv_nsec = 1000000000 / hz;
    244 
    245 		error = copyout(&ts, SCARG(uap, tp), sizeof(ts));
    246 	}
    247 
    248 	return error;
    249 }
    250 
    251 /* ARGSUSED */
    252 int
    253 sys_nanosleep(struct lwp *l, void *v, register_t *retval)
    254 {
    255 	static int nanowait;
    256 	struct sys_nanosleep_args/* {
    257 		syscallarg(struct timespec *) rqtp;
    258 		syscallarg(struct timespec *) rmtp;
    259 	} */ *uap = v;
    260 	struct timespec rqt;
    261 	struct timespec rmt;
    262 	struct timeval atv, utv;
    263 	int error, s, timo;
    264 
    265 	error = copyin((caddr_t)SCARG(uap, rqtp), (caddr_t)&rqt,
    266 		       sizeof(struct timespec));
    267 	if (error)
    268 		return (error);
    269 
    270 	TIMESPEC_TO_TIMEVAL(&atv,&rqt)
    271 	if (itimerfix(&atv) || atv.tv_sec > 1000000000)
    272 		return (EINVAL);
    273 
    274 	s = splclock();
    275 	timeradd(&atv,&time,&atv);
    276 	timo = hzto(&atv);
    277 	/*
    278 	 * Avoid inadvertantly sleeping forever
    279 	 */
    280 	if (timo == 0)
    281 		timo = 1;
    282 	splx(s);
    283 
    284 	error = tsleep(&nanowait, PWAIT | PCATCH, "nanosleep", timo);
    285 	if (error == ERESTART)
    286 		error = EINTR;
    287 	if (error == EWOULDBLOCK)
    288 		error = 0;
    289 
    290 	if (SCARG(uap, rmtp)) {
    291 		int error;
    292 
    293 		s = splclock();
    294 		utv = time;
    295 		splx(s);
    296 
    297 		timersub(&atv, &utv, &utv);
    298 		if (utv.tv_sec < 0)
    299 			timerclear(&utv);
    300 
    301 		TIMEVAL_TO_TIMESPEC(&utv,&rmt);
    302 		error = copyout((caddr_t)&rmt, (caddr_t)SCARG(uap,rmtp),
    303 			sizeof(rmt));
    304 		if (error)
    305 			return (error);
    306 	}
    307 
    308 	return error;
    309 }
    310 
    311 /* ARGSUSED */
    312 int
    313 sys_gettimeofday(struct lwp *l, void *v, register_t *retval)
    314 {
    315 	struct sys_gettimeofday_args /* {
    316 		syscallarg(struct timeval *) tp;
    317 		syscallarg(struct timezone *) tzp;
    318 	} */ *uap = v;
    319 	struct timeval atv;
    320 	int error = 0;
    321 	struct timezone tzfake;
    322 
    323 	if (SCARG(uap, tp)) {
    324 		microtime(&atv);
    325 		error = copyout(&atv, SCARG(uap, tp), sizeof(atv));
    326 		if (error)
    327 			return (error);
    328 	}
    329 	if (SCARG(uap, tzp)) {
    330 		/*
    331 		 * NetBSD has no kernel notion of time zone, so we just
    332 		 * fake up a timezone struct and return it if demanded.
    333 		 */
    334 		tzfake.tz_minuteswest = 0;
    335 		tzfake.tz_dsttime = 0;
    336 		error = copyout(&tzfake, SCARG(uap, tzp), sizeof(tzfake));
    337 	}
    338 	return (error);
    339 }
    340 
    341 /* ARGSUSED */
    342 int
    343 sys_settimeofday(struct lwp *l, void *v, register_t *retval)
    344 {
    345 	struct sys_settimeofday_args /* {
    346 		syscallarg(const struct timeval *) tv;
    347 		syscallarg(const struct timezone *) tzp;
    348 	} */ *uap = v;
    349 	struct proc *p = l->l_proc;
    350 	struct timeval atv;
    351 	struct timezone atz;
    352 	struct timeval *tv = NULL;
    353 	struct timezone *tzp = NULL;
    354 	int error;
    355 
    356 	if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
    357 		return (error);
    358 
    359 	/* Verify all parameters before changing time. */
    360 	if (SCARG(uap, tv)) {
    361 		if ((error = copyin(SCARG(uap, tv), &atv, sizeof(atv))) != 0)
    362 			return (error);
    363 		tv = &atv;
    364 	}
    365 	/* XXX since we don't use tz, probably no point in doing copyin. */
    366 	if (SCARG(uap, tzp)) {
    367 		if ((error = copyin(SCARG(uap, tzp), &atz, sizeof(atz))) != 0)
    368 			return (error);
    369 		tzp = &atz;
    370 	}
    371 
    372 	return settimeofday1(tv, tzp, p);
    373 }
    374 
    375 int
    376 settimeofday1(struct timeval *tv, struct timezone *tzp, struct proc *p)
    377 {
    378 	int error;
    379 
    380 	if (tv)
    381 		if ((error = settime(tv)) != 0)
    382 			return (error);
    383 	/*
    384 	 * NetBSD has no kernel notion of time zone, and only an
    385 	 * obsolete program would try to set it, so we log a warning.
    386 	 */
    387 	if (tzp)
    388 		log(LOG_WARNING, "pid %d attempted to set the "
    389 		    "(obsolete) kernel time zone\n", p->p_pid);
    390 	return (0);
    391 }
    392 
    393 int	tickdelta;			/* current clock skew, us. per tick */
    394 long	timedelta;			/* unapplied time correction, us. */
    395 long	bigadj = 1000000;		/* use 10x skew above bigadj us. */
    396 
    397 /* ARGSUSED */
    398 int
    399 sys_adjtime(struct lwp *l, void *v, register_t *retval)
    400 {
    401 	struct sys_adjtime_args /* {
    402 		syscallarg(const struct timeval *) delta;
    403 		syscallarg(struct timeval *) olddelta;
    404 	} */ *uap = v;
    405 	struct proc *p = l->l_proc;
    406 	struct timeval atv;
    407 	struct timeval *oatv = NULL;
    408 	int error;
    409 
    410 	if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
    411 		return (error);
    412 
    413 	error = copyin(SCARG(uap, delta), &atv, sizeof(struct timeval));
    414 	if (error)
    415 		return (error);
    416 
    417 	if (SCARG(uap, olddelta) != NULL) {
    418 		if (uvm_useracc((caddr_t)SCARG(uap, olddelta),
    419 		    sizeof(struct timeval), B_WRITE) == FALSE)
    420 			return (EFAULT);
    421 		oatv = SCARG(uap, olddelta);
    422 	}
    423 
    424 	return adjtime1(&atv, oatv, p);
    425 }
    426 
    427 int
    428 adjtime1(struct timeval *delta, struct timeval *olddelta, struct proc *p)
    429 {
    430 	long ndelta, ntickdelta, odelta;
    431 	int s;
    432 
    433 	/*
    434 	 * Compute the total correction and the rate at which to apply it.
    435 	 * Round the adjustment down to a whole multiple of the per-tick
    436 	 * delta, so that after some number of incremental changes in
    437 	 * hardclock(), tickdelta will become zero, lest the correction
    438 	 * overshoot and start taking us away from the desired final time.
    439 	 */
    440 	ndelta = delta->tv_sec * 1000000 + delta->tv_usec;
    441 	if (ndelta > bigadj || ndelta < -bigadj)
    442 		ntickdelta = 10 * tickadj;
    443 	else
    444 		ntickdelta = tickadj;
    445 	if (ndelta % ntickdelta)
    446 		ndelta = ndelta / ntickdelta * ntickdelta;
    447 
    448 	/*
    449 	 * To make hardclock()'s job easier, make the per-tick delta negative
    450 	 * if we want time to run slower; then hardclock can simply compute
    451 	 * tick + tickdelta, and subtract tickdelta from timedelta.
    452 	 */
    453 	if (ndelta < 0)
    454 		ntickdelta = -ntickdelta;
    455 	s = splclock();
    456 	odelta = timedelta;
    457 	timedelta = ndelta;
    458 	tickdelta = ntickdelta;
    459 	splx(s);
    460 
    461 	if (olddelta) {
    462 		delta->tv_sec = odelta / 1000000;
    463 		delta->tv_usec = odelta % 1000000;
    464 		(void) copyout(delta, olddelta, sizeof(struct timeval));
    465 	}
    466 	return (0);
    467 }
    468 
    469 /*
    470  * Interval timer support. Both the BSD getitimer() family and the POSIX
    471  * timer_*() family of routines are supported.
    472  *
    473  * All timers are kept in an array pointed to by p_timers, which is
    474  * allocated on demand - many processes don't use timers at all. The
    475  * first three elements in this array are reserved for the BSD timers:
    476  * element 0 is ITIMER_REAL, element 1 is ITIMER_VIRTUAL, and element
    477  * 2 is ITIMER_PROF. The rest may be allocated by the timer_create()
    478  * syscall.
    479  *
    480  * Realtime timers are kept in the ptimer structure as an absolute
    481  * time; virtual time timers are kept as deltas.  Virtual time timers
    482  * are processed in the hardclock() routine of kern_clock.c.  The real
    483  * time timer is processed by a callout routine, called from the
    484  * softclock() routine.  Since a callout may be delayed in real time
    485  * due to interrupt processing in the system, it is possible for the
    486  * real time timeout routine (realtimeexpire, given below), to be
    487  * delayed in real time past when it is supposed to occur.  It does
    488  * not suffice, therefore, to reload the real timer .it_value from the
    489  * real time timers .it_interval.  Rather, we compute the next time in
    490  * absolute time the timer should go off.
    491  */
    492 
    493 /* Allocate a POSIX realtime timer. */
    494 int
    495 sys_timer_create(struct lwp *l, void *v, register_t *retval)
    496 {
    497 	struct sys_timer_create_args /* {
    498 		syscallarg(clockid_t) clock_id;
    499 		syscallarg(struct sigevent *) evp;
    500 		syscallarg(timer_t *) timerid;
    501 	} */ *uap = v;
    502 	struct proc *p = l->l_proc;
    503 	clockid_t id;
    504 	struct sigevent *evp;
    505 	struct ptimer *pt;
    506 	int timerid, error;
    507 
    508 	id = SCARG(uap, clock_id);
    509 	if (id != CLOCK_REALTIME)
    510 		return (EINVAL);
    511 
    512 	if (p->p_timers == NULL)
    513 		timers_alloc(p);
    514 
    515 	for (timerid = 3; timerid < TIMER_MAX; timerid++)
    516 		if (p->p_timers[timerid] == NULL)
    517 			break;
    518 
    519 	if (timerid == TIMER_MAX)
    520 		return EAGAIN;
    521 
    522 	pt = pool_get(&ptimer_pool, PR_WAITOK);
    523 	evp = SCARG(uap, evp);
    524 	if (evp) {
    525 		if (((error =
    526 		    copyin(evp, &pt->pt_ev, sizeof (pt->pt_ev))) != 0) ||
    527 		    ((pt->pt_ev.sigev_notify < SIGEV_NONE) ||
    528 			(pt->pt_ev.sigev_notify > SIGEV_SA)) ||
    529 		    ((pt->pt_ev.sigev_notify == SIGEV_SA) &&
    530 			!(p->p_flag & P_SA))) {
    531 			pool_put(&ptimer_pool, pt);
    532 			return (error ? error : EINVAL);
    533 		}
    534 	} else {
    535 		pt->pt_ev.sigev_notify = SIGEV_SIGNAL;
    536 		pt->pt_ev.sigev_signo = SIGALRM;
    537 		pt->pt_ev.sigev_value.sival_int = timerid;
    538 	}
    539 
    540 	callout_init(&pt->pt_ch);
    541 	pt->pt_type = CLOCK_REALTIME;
    542 	pt->pt_proc = p;
    543 	pt->pt_overruns = 0;
    544 
    545 	p->p_timers[timerid] = pt;
    546 
    547 	return copyout(&timerid, SCARG(uap, timerid), sizeof(timerid));
    548 }
    549 
    550 
    551 /* Delete a POSIX realtime timer */
    552 int
    553 sys_timer_delete(struct lwp *l, void *v, register_t *retval)
    554 {
    555 	struct sys_timer_delete_args /*  {
    556 		syscallarg(timer_t) timerid;
    557 	} */ *uap = v;
    558 	struct proc *p = l->l_proc;
    559 	int timerid;
    560 	struct ptimer *pt;
    561 
    562 	timerid = SCARG(uap, timerid);
    563 
    564 	if ((p->p_timers == NULL) ||
    565 	    (timerid < 2) || (timerid >= TIMER_MAX) ||
    566 	    ((pt = p->p_timers[timerid]) == NULL))
    567 		return (EINVAL);
    568 
    569 	callout_stop(&pt->pt_ch);
    570 	p->p_timers[timerid] = NULL;
    571 	pool_put(&ptimer_pool, pt);
    572 
    573 	return (0);
    574 }
    575 
    576 /* Set and arm a POSIX realtime timer */
    577 int
    578 sys_timer_settime(struct lwp *l, void *v, register_t *retval)
    579 {
    580 	struct sys_timer_settime_args /* {
    581 		syscallarg(timer_t) timerid;
    582 		syscallarg(int) flags;
    583 		syscallarg(const struct itimerspec *) value;
    584 		syscallarg(struct itimerspec *) ovalue;
    585 	} */ *uap = v;
    586 	struct proc *p = l->l_proc;
    587 	int error, s, timerid;
    588 	struct itimerval val, oval;
    589 	struct itimerspec value, ovalue;
    590 	struct ptimer *pt;
    591 
    592 	timerid = SCARG(uap, timerid);
    593 
    594 	if ((p->p_timers == NULL) ||
    595 	    (timerid < 2) || (timerid >= TIMER_MAX) ||
    596 	    ((pt = p->p_timers[timerid]) == NULL))
    597 		return (EINVAL);
    598 
    599 	if ((error = copyin(SCARG(uap, value), &value,
    600 	    sizeof(struct itimerspec))) != 0)
    601 		return (error);
    602 
    603 	TIMESPEC_TO_TIMEVAL(&val.it_value, &value.it_value);
    604 	TIMESPEC_TO_TIMEVAL(&val.it_interval, &value.it_interval);
    605 	if (itimerfix(&val.it_value) || itimerfix(&val.it_interval))
    606 		return (EINVAL);
    607 
    608 	oval = pt->pt_time;
    609 	pt->pt_time = val;
    610 
    611 	s = splclock();
    612 	callout_stop(&pt->pt_ch);
    613 	if (timerisset(&pt->pt_time.it_value)) {
    614 		if ((SCARG(uap, flags) & TIMER_ABSTIME) == 0)
    615 			timeradd(&pt->pt_time.it_value, &time,
    616 			    &pt->pt_time.it_value);
    617 		/*
    618 		 * Don't need to check hzto() return value, here.
    619 		 * callout_reset() does it for us.
    620 		 */
    621 		callout_reset(&pt->pt_ch, hzto(&pt->pt_time.it_value),
    622 		    realtimerexpire, pt);
    623 	}
    624 	splx(s);
    625 
    626 	if (SCARG(uap, ovalue)) {
    627 		TIMEVAL_TO_TIMESPEC(&oval.it_value, &ovalue.it_value);
    628 		TIMEVAL_TO_TIMESPEC(&oval.it_interval, &ovalue.it_interval);
    629 		return copyout(&ovalue, SCARG(uap, ovalue),
    630 		    sizeof(struct itimerspec));
    631 	}
    632 
    633 	return (0);
    634 }
    635 
    636 /* Return the time remaining until a POSIX timer fires. */
    637 int
    638 sys_timer_gettime(struct lwp *l, void *v, register_t *retval)
    639 {
    640 	struct sys_timer_gettime_args /* {
    641 		syscallarg(timer_t) timerid;
    642 		syscallarg(struct itimerspec *) value;
    643 	} */ *uap = v;
    644 	struct itimerval aitv;
    645 	struct itimerspec its;
    646 	struct proc *p = l->l_proc;
    647 	int timerid;
    648 	struct ptimer *pt;
    649 
    650 	timerid = SCARG(uap, timerid);
    651 
    652 	if ((p->p_timers == NULL) ||
    653 	    (timerid < 2) || (timerid >= TIMER_MAX) ||
    654 	    ((pt = p->p_timers[timerid]) == NULL))
    655 		return (EINVAL);
    656 
    657 	aitv = pt->pt_time;
    658 
    659 	/*
    660 	 * Real-time timers are kept in absolute time, but this interface
    661 	 * is supposed to return a relative time.
    662 	 */
    663 	if (timerisset(&aitv.it_value)) {
    664 		if (timercmp(&aitv.it_value, &time, <))
    665 			timerclear(&aitv.it_value);
    666 		else
    667 			timersub(&aitv.it_value, &time, &aitv.it_value);
    668 	}
    669 
    670 	TIMEVAL_TO_TIMESPEC(&aitv.it_interval, &its.it_interval);
    671 	TIMEVAL_TO_TIMESPEC(&aitv.it_value, &its.it_value);
    672 
    673 	return copyout(&its, SCARG(uap, value), sizeof(its));
    674 }
    675 
    676 /*
    677  * Return the count of the number of times a periodic timer expired
    678  * while a notification was already pending. The counter is reset when
    679  * a timer expires and a notification can be posted.
    680  */
    681 int
    682 sys_timer_getoverrun(struct lwp *l, void *v, register_t *retval)
    683 {
    684 	struct sys_timer_getoverrun_args /* {
    685 		syscallarg(timer_t) timerid;
    686 	} */ *uap = v;
    687 	struct proc *p = l->l_proc;
    688 	int timerid;
    689 	struct ptimer *pt;
    690 
    691 	timerid = SCARG(uap, timerid);
    692 
    693 	if ((p->p_timers == NULL) ||
    694 	    (timerid < 2) || (timerid >= TIMER_MAX) ||
    695 	    ((pt = p->p_timers[timerid]) == NULL))
    696 		return (EINVAL);
    697 
    698 	*retval = pt->pt_overruns;
    699 
    700 	return (0);
    701 }
    702 
    703 /* Glue function that triggers an upcall; called from userret(). */
    704 static void
    705 realtimerupcall(struct lwp *l, void *arg)
    706 {
    707 	struct ptimer *pt;
    708 
    709 	pt = (struct ptimer *)arg;
    710 	sa_upcall(l, SA_UPCALL_SIGEV, NULL, l, sizeof(struct sigevent),
    711 	    &pt->pt_ev);
    712 
    713 	/* The upcall should only be generated once. */
    714 	l->l_proc->p_userret = NULL;
    715 }
    716 
    717 
    718 /*
    719  * Real interval timer expired:
    720  * send process whose timer expired an alarm signal.
    721  * If time is not set up to reload, then just return.
    722  * Else compute next time timer should go off which is > current time.
    723  * This is where delay in processing this timeout causes multiple
    724  * SIGALRM calls to be compressed into one.
    725  */
    726 void
    727 realtimerexpire(void *arg)
    728 {
    729 	struct ptimer *pt;
    730 	struct proc *p;
    731 	int s;
    732 
    733 	pt = (struct ptimer *)arg;
    734 	p = pt->pt_proc;
    735 	if (pt->pt_ev.sigev_notify == SIGEV_SIGNAL) {
    736 		/*
    737 		 * No RT signal infrastructure exists at this time;
    738 		 * just post the signal number and throw away the
    739 		 * value.
    740 		 */
    741 		if (sigismember(&p->p_sigctx.ps_siglist, pt->pt_ev.sigev_signo))
    742 			pt->pt_overruns++;
    743 		else {
    744 			pt->pt_overruns = 0;
    745 			psignal(p, pt->pt_ev.sigev_signo);
    746 		}
    747 	} else if (pt->pt_ev.sigev_notify == SIGEV_SA) {
    748 		/* Cause the process to generate an upcall when it returns. */
    749 		if (p->p_userret == NULL) {
    750 			pt->pt_overruns = 0;
    751 			p->p_userret = realtimerupcall;
    752 			p->p_userret_arg = pt;
    753 		} else
    754 			pt->pt_overruns++;
    755 	}
    756 	if (!timerisset(&pt->pt_time.it_interval)) {
    757 		timerclear(&pt->pt_time.it_value);
    758 		return;
    759 	}
    760 	for (;;) {
    761 		s = splclock();
    762 		timeradd(&pt->pt_time.it_value,
    763 		    &pt->pt_time.it_interval, &pt->pt_time.it_value);
    764 		if (timercmp(&pt->pt_time.it_value, &time, >)) {
    765 			/*
    766 			 * Don't need to check hzto() return value, here.
    767 			 * callout_reset() does it for us.
    768 			 */
    769 			callout_reset(&pt->pt_ch, hzto(&pt->pt_time.it_value),
    770 			    realtimerexpire, pt);
    771 			splx(s);
    772 			return;
    773 		}
    774 		splx(s);
    775 		pt->pt_overruns++;
    776 	}
    777 }
    778 
    779 /* BSD routine to get the value of an interval timer. */
    780 /* ARGSUSED */
    781 int
    782 sys_getitimer(struct lwp *l, void *v, register_t *retval)
    783 {
    784 	struct sys_getitimer_args /* {
    785 		syscallarg(int) which;
    786 		syscallarg(struct itimerval *) itv;
    787 	} */ *uap = v;
    788 	struct proc *p = l->l_proc;
    789 	struct itimerval aitv;
    790 	int s, which;
    791 
    792 	which = SCARG(uap, which);
    793 
    794 	if ((u_int)which > ITIMER_PROF)
    795 		return (EINVAL);
    796 
    797 	if ((p->p_timers == NULL) || (p->p_timers[which] == NULL)) {
    798 		timerclear(&aitv.it_value);
    799 		timerclear(&aitv.it_interval);
    800 	} else {
    801 		s = splclock();
    802 		if (which == ITIMER_REAL) {
    803 			/*
    804 			 * Convert from absolute to relative time in
    805 			 * .it_value part of real time timer.  If time
    806 			 * for real time timer has passed return 0,
    807 			 * else return difference between current time
    808 			 * and time for the timer to go off.
    809 			 */
    810 			aitv = p->p_timers[ITIMER_REAL]->pt_time;
    811 			if (timerisset(&aitv.it_value)) {
    812 				if (timercmp(&aitv.it_value, &time, <))
    813 					timerclear(&aitv.it_value);
    814 				else
    815 					timersub(&aitv.it_value, &time, &aitv.it_value);
    816 			}
    817 		} else
    818 			aitv = p->p_timers[which]->pt_time;
    819 		splx(s);
    820 	}
    821 
    822 	return (copyout(&aitv, SCARG(uap, itv), sizeof(struct itimerval)));
    823 
    824 }
    825 
    826 /* BSD routine to set/arm an interval timer. */
    827 /* ARGSUSED */
    828 int
    829 sys_setitimer(struct lwp *l, void *v, register_t *retval)
    830 {
    831 	struct sys_setitimer_args /* {
    832 		syscallarg(int) which;
    833 		syscallarg(const struct itimerval *) itv;
    834 		syscallarg(struct itimerval *) oitv;
    835 	} */ *uap = v;
    836 	struct proc *p = l->l_proc;
    837 	int which = SCARG(uap, which);
    838 	struct sys_getitimer_args getargs;
    839 	struct itimerval aitv;
    840 	const struct itimerval *itvp;
    841 	struct ptimer *pt;
    842 	int s, error;
    843 
    844 	if ((u_int)which > ITIMER_PROF)
    845 		return (EINVAL);
    846 	itvp = SCARG(uap, itv);
    847 	if (itvp &&
    848 	    (error = copyin(itvp, &aitv, sizeof(struct itimerval)) != 0))
    849 		return (error);
    850 	if (SCARG(uap, oitv) != NULL) {
    851 		SCARG(&getargs, which) = which;
    852 		SCARG(&getargs, itv) = SCARG(uap, oitv);
    853 		if ((error = sys_getitimer(l, &getargs, retval)) != 0)
    854 			return (error);
    855 	}
    856 	if (itvp == 0)
    857 		return (0);
    858 	if (itimerfix(&aitv.it_value) || itimerfix(&aitv.it_interval))
    859 		return (EINVAL);
    860 
    861 	/*
    862 	 * Don't bother allocating data structures if the process just
    863 	 * wants to clear the timer.
    864 	 */
    865 	if (!timerisset(&aitv.it_value) &&
    866 	    ((p->p_timers == NULL) || (p->p_timers[which] == NULL)))
    867 		return (0);
    868 
    869 	if (p->p_timers == NULL)
    870 		timers_alloc(p);
    871 	if (p->p_timers[which] == NULL) {
    872 		pt = pool_get(&ptimer_pool, PR_WAITOK);
    873 		callout_init(&pt->pt_ch);
    874 		pt->pt_ev.sigev_notify = SIGEV_SIGNAL;
    875 		pt->pt_overruns = 0;
    876 		pt->pt_proc = p;
    877 		pt->pt_type = which;
    878 		switch (which) {
    879 		case ITIMER_REAL:
    880 			pt->pt_ev.sigev_signo = SIGALRM;
    881 			break;
    882 		case ITIMER_VIRTUAL:
    883 			pt->pt_ev.sigev_signo = SIGVTALRM;
    884 			break;
    885 		case ITIMER_PROF:
    886 			pt->pt_ev.sigev_signo = SIGPROF;
    887 			break;
    888 		}
    889 	} else
    890 		pt = p->p_timers[which];
    891 
    892 	pt->pt_time = aitv;
    893 	p->p_timers[which] = pt;
    894 	if (which == ITIMER_REAL) {
    895 		s = splclock();
    896 		callout_stop(&pt->pt_ch);
    897 		if (timerisset(&pt->pt_time.it_value)) {
    898 			timeradd(&pt->pt_time.it_value, &time,
    899 			    &pt->pt_time.it_value);
    900 			/*
    901 			 * Don't need to check hzto() return value, here.
    902 			 * callout_reset() does it for us.
    903 			 */
    904 			callout_reset(&pt->pt_ch, hzto(&pt->pt_time.it_value),
    905 			    realtimerexpire, pt);
    906 		}
    907 		splx(s);
    908 	}
    909 
    910 	return (0);
    911 }
    912 
    913 /* Utility routines to manage the array of pointers to timers. */
    914 void
    915 timers_alloc(struct proc *p)
    916 {
    917 	int i;
    918 	struct ptimer **pts;
    919 
    920 	pts = malloc(TIMER_MAX * sizeof(struct timer *), M_SUBPROC, 0);
    921 	for (i = 0; i < TIMER_MAX; i++)
    922 		pts[i] = NULL;
    923 	p->p_timers = pts;
    924 }
    925 
    926 void
    927 timers_free(struct proc *p)
    928 {
    929 	int i;
    930 	struct ptimer *pt, **pts;
    931 
    932 	if (p->p_timers) {
    933 		pts = p->p_timers;
    934 		p->p_timers = NULL;
    935 		for (i = 0; i < TIMER_MAX; i++)
    936 			if ((pt = pts[i]) != NULL) {
    937 				if (pt->pt_type == CLOCK_REALTIME)
    938 					callout_stop(&pt->pt_ch);
    939 				pool_put(&ptimer_pool, pt);
    940 			}
    941 		free(pts, M_SUBPROC);
    942 	}
    943 }
    944 
    945 /*
    946  * Check that a proposed value to load into the .it_value or
    947  * .it_interval part of an interval timer is acceptable, and
    948  * fix it to have at least minimal value (i.e. if it is less
    949  * than the resolution of the clock, round it up.)
    950  */
    951 int
    952 itimerfix(struct timeval *tv)
    953 {
    954 
    955 	if (tv->tv_sec < 0 || tv->tv_usec < 0 || tv->tv_usec >= 1000000)
    956 		return (EINVAL);
    957 	if (tv->tv_sec == 0 && tv->tv_usec != 0 && tv->tv_usec < tick)
    958 		tv->tv_usec = tick;
    959 	return (0);
    960 }
    961 
    962 /*
    963  * Decrement an interval timer by a specified number
    964  * of microseconds, which must be less than a second,
    965  * i.e. < 1000000.  If the timer expires, then reload
    966  * it.  In this case, carry over (usec - old value) to
    967  * reduce the value reloaded into the timer so that
    968  * the timer does not drift.  This routine assumes
    969  * that it is called in a context where the timers
    970  * on which it is operating cannot change in value.
    971  */
    972 int
    973 itimerdecr(struct itimerval *itp, int usec)
    974 {
    975 
    976 	if (itp->it_value.tv_usec < usec) {
    977 		if (itp->it_value.tv_sec == 0) {
    978 			/* expired, and already in next interval */
    979 			usec -= itp->it_value.tv_usec;
    980 			goto expire;
    981 		}
    982 		itp->it_value.tv_usec += 1000000;
    983 		itp->it_value.tv_sec--;
    984 	}
    985 	itp->it_value.tv_usec -= usec;
    986 	usec = 0;
    987 	if (timerisset(&itp->it_value))
    988 		return (1);
    989 	/* expired, exactly at end of interval */
    990 expire:
    991 	if (timerisset(&itp->it_interval)) {
    992 		itp->it_value = itp->it_interval;
    993 		itp->it_value.tv_usec -= usec;
    994 		if (itp->it_value.tv_usec < 0) {
    995 			itp->it_value.tv_usec += 1000000;
    996 			itp->it_value.tv_sec--;
    997 		}
    998 	} else
    999 		itp->it_value.tv_usec = 0;		/* sec is already 0 */
   1000 	return (0);
   1001 }
   1002 
   1003 /*
   1004  * ratecheck(): simple time-based rate-limit checking.  see ratecheck(9)
   1005  * for usage and rationale.
   1006  */
   1007 int
   1008 ratecheck(struct timeval *lasttime, const struct timeval *mininterval)
   1009 {
   1010 	struct timeval tv, delta;
   1011 	int s, rv = 0;
   1012 
   1013 	s = splclock();
   1014 	tv = mono_time;
   1015 	splx(s);
   1016 
   1017 	timersub(&tv, lasttime, &delta);
   1018 
   1019 	/*
   1020 	 * check for 0,0 is so that the message will be seen at least once,
   1021 	 * even if interval is huge.
   1022 	 */
   1023 	if (timercmp(&delta, mininterval, >=) ||
   1024 	    (lasttime->tv_sec == 0 && lasttime->tv_usec == 0)) {
   1025 		*lasttime = tv;
   1026 		rv = 1;
   1027 	}
   1028 
   1029 	return (rv);
   1030 }
   1031 
   1032 /*
   1033  * ppsratecheck(): packets (or events) per second limitation.
   1034  */
   1035 int
   1036 ppsratecheck(struct timeval *lasttime, int *curpps, int maxpps)
   1037 {
   1038 	struct timeval tv, delta;
   1039 	int s, rv;
   1040 
   1041 	s = splclock();
   1042 	tv = mono_time;
   1043 	splx(s);
   1044 
   1045 	timersub(&tv, lasttime, &delta);
   1046 
   1047 	/*
   1048 	 * check for 0,0 is so that the message will be seen at least once.
   1049 	 * if more than one second have passed since the last update of
   1050 	 * lasttime, reset the counter.
   1051 	 *
   1052 	 * we do increment *curpps even in *curpps < maxpps case, as some may
   1053 	 * try to use *curpps for stat purposes as well.
   1054 	 */
   1055 	if ((lasttime->tv_sec == 0 && lasttime->tv_usec == 0) ||
   1056 	    delta.tv_sec >= 1) {
   1057 		*lasttime = tv;
   1058 		*curpps = 0;
   1059 		rv = 1;
   1060 	} else if (maxpps < 0)
   1061 		rv = 1;
   1062 	else if (*curpps < maxpps)
   1063 		rv = 1;
   1064 	else
   1065 		rv = 0;
   1066 
   1067 #if 1 /*DIAGNOSTIC?*/
   1068 	/* be careful about wrap-around */
   1069 	if (*curpps + 1 > *curpps)
   1070 		*curpps = *curpps + 1;
   1071 #else
   1072 	/*
   1073 	 * assume that there's not too many calls to this function.
   1074 	 * not sure if the assumption holds, as it depends on *caller's*
   1075 	 * behavior, not the behavior of this function.
   1076 	 * IMHO it is wrong to make assumption on the caller's behavior,
   1077 	 * so the above #if is #if 1, not #ifdef DIAGNOSTIC.
   1078 	 */
   1079 	*curpps = *curpps + 1;
   1080 #endif
   1081 
   1082 	return (rv);
   1083 }
   1084