kern_time.c revision 108511
11541Srgrimes/*
21541Srgrimes * Copyright (c) 1982, 1986, 1989, 1993
31541Srgrimes *	The Regents of the University of California.  All rights reserved.
41541Srgrimes *
51541Srgrimes * Redistribution and use in source and binary forms, with or without
61541Srgrimes * modification, are permitted provided that the following conditions
71541Srgrimes * are met:
81541Srgrimes * 1. Redistributions of source code must retain the above copyright
91541Srgrimes *    notice, this list of conditions and the following disclaimer.
101541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111541Srgrimes *    notice, this list of conditions and the following disclaimer in the
121541Srgrimes *    documentation and/or other materials provided with the distribution.
131541Srgrimes * 3. All advertising materials mentioning features or use of this software
141541Srgrimes *    must display the following acknowledgement:
151541Srgrimes *	This product includes software developed by the University of
161541Srgrimes *	California, Berkeley and its contributors.
171541Srgrimes * 4. Neither the name of the University nor the names of its contributors
181541Srgrimes *    may be used to endorse or promote products derived from this software
191541Srgrimes *    without specific prior written permission.
201541Srgrimes *
211541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
221541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
231541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
241541Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
251541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
261541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
271541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
281541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
291541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
301541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
311541Srgrimes * SUCH DAMAGE.
321541Srgrimes *
331541Srgrimes *	@(#)kern_time.c	8.1 (Berkeley) 6/10/93
3450477Speter * $FreeBSD: head/sys/kern/kern_time.c 108511 2002-12-31 18:22:12Z sam $
351541Srgrimes */
361541Srgrimes
37106369Srwatson#include "opt_mac.h"
38106369Srwatson
391541Srgrimes#include <sys/param.h>
4048274Speter#include <sys/systm.h>
4176166Smarkm#include <sys/lock.h>
4276166Smarkm#include <sys/mutex.h>
4312221Sbde#include <sys/sysproto.h>
441541Srgrimes#include <sys/resourcevar.h>
453308Sphk#include <sys/signalvar.h>
461541Srgrimes#include <sys/kernel.h>
47106369Srwatson#include <sys/mac.h>
481541Srgrimes#include <sys/systm.h>
4925583Speter#include <sys/sysent.h>
501541Srgrimes#include <sys/proc.h>
5125656Speter#include <sys/time.h>
5258377Sphk#include <sys/timetc.h>
531541Srgrimes#include <sys/vnode.h>
5476166Smarkm
5526335Speter#include <vm/vm.h>
5626335Speter#include <vm/vm_extern.h>
571541Srgrimes
589369Sdgstruct timezone tz;
599369Sdg
608876Srgrimes/*
611541Srgrimes * Time of day and interval timer support.
621541Srgrimes *
631541Srgrimes * These routines provide the kernel entry points to get and set
641541Srgrimes * the time-of-day and per-process interval timers.  Subroutines
651541Srgrimes * here provide support for adding and subtracting timeval structures
661541Srgrimes * and decrementing interval timers, optionally reloading the interval
671541Srgrimes * timers when they expire.
681541Srgrimes */
691541Srgrimes
7092723Salfredstatic int	nanosleep1(struct thread *td, struct timespec *rqt,
7192723Salfred		    struct timespec *rmt);
7294343Sjhbstatic int	settime(struct thread *, struct timeval *);
7392723Salfredstatic void	timevalfix(struct timeval *);
7492723Salfredstatic void	no_lease_updatetime(int);
7513016Sbde
7630739Sphkstatic void
7730739Sphkno_lease_updatetime(deltat)
7830739Sphk	int deltat;
7930739Sphk{
8030739Sphk}
8130739Sphk
8292723Salfredvoid (*lease_updatetime)(int)  = no_lease_updatetime;
8330739Sphk
8425583Speterstatic int
85102074Sphksettime(struct thread *td, struct timeval *tv)
8625583Speter{
8745433Snsayer	struct timeval delta, tv1, tv2;
8845438Snsayer	static struct timeval maxtime, laststep;
8933690Sphk	struct timespec ts;
9025583Speter	int s;
9125583Speter
9225656Speter	s = splclock();
9333818Sbde	microtime(&tv1);
9435029Sphk	delta = *tv;
9535029Sphk	timevalsub(&delta, &tv1);
9625583Speter
9725583Speter	/*
9833818Sbde	 * If the system is secure, we do not allow the time to be
9945433Snsayer	 * set to a value earlier than 1 second less than the highest
10045433Snsayer	 * time we have yet seen. The worst a miscreant can do in
10145433Snsayer	 * this circumstance is "freeze" time. He couldn't go
10245433Snsayer	 * back to the past.
10345438Snsayer	 *
10445438Snsayer	 * We similarly do not allow the clock to be stepped more
10545438Snsayer	 * than one second, nor more than once per second. This allows
10645438Snsayer	 * a miscreant to make the clock march double-time, but no worse.
10725583Speter	 */
10894343Sjhb	if (securelevel_gt(td->td_ucred, 1) != 0) {
10945433Snsayer		if (delta.tv_sec < 0 || delta.tv_usec < 0) {
11045437Smjacob			/*
11145438Snsayer			 * Update maxtime to latest time we've seen.
11245437Smjacob			 */
11345437Smjacob			if (tv1.tv_sec > maxtime.tv_sec)
11445437Smjacob				maxtime = tv1;
11545437Smjacob			tv2 = *tv;
11645437Smjacob			timevalsub(&tv2, &maxtime);
11745437Smjacob			if (tv2.tv_sec < -1) {
11845437Smjacob				tv->tv_sec = maxtime.tv_sec - 1;
11945433Snsayer				printf("Time adjustment clamped to -1 second\n");
12045433Snsayer			}
12145437Smjacob		} else {
12245438Snsayer			if (tv1.tv_sec == laststep.tv_sec) {
12345438Snsayer				splx(s);
12445438Snsayer				return (EPERM);
12545438Snsayer			}
12645438Snsayer			if (delta.tv_sec > 1) {
12745438Snsayer				tv->tv_sec = tv1.tv_sec + 1;
12845438Snsayer				printf("Time adjustment clamped to +1 second\n");
12945438Snsayer			}
13045438Snsayer			laststep = *tv;
13145433Snsayer		}
13233818Sbde	}
13333818Sbde
13433690Sphk	ts.tv_sec = tv->tv_sec;
13533690Sphk	ts.tv_nsec = tv->tv_usec * 1000;
13694343Sjhb	mtx_lock(&Giant);
13758377Sphk	tc_setclock(&ts);
13825583Speter	(void) splsoftclock();
13925583Speter	lease_updatetime(delta.tv_sec);
14025583Speter	splx(s);
14125583Speter	resettodr();
14294343Sjhb	mtx_unlock(&Giant);
14325583Speter	return (0);
14425583Speter}
14525583Speter
14612221Sbde#ifndef _SYS_SYSPROTO_H_
14725583Speterstruct clock_gettime_args {
14825583Speter	clockid_t clock_id;
14925583Speter	struct	timespec *tp;
15025583Speter};
15125583Speter#endif
15225656Speter
15382746Sdillon/*
15482746Sdillon * MPSAFE
15582746Sdillon */
15625583Speter/* ARGSUSED */
15725583Speterint
158102074Sphkclock_gettime(struct thread *td, struct clock_gettime_args *uap)
15925583Speter{
16025583Speter	struct timespec ats;
16125583Speter
162107849Salfred	if (uap->clock_id != CLOCK_REALTIME)
16325583Speter		return (EINVAL);
16482746Sdillon	mtx_lock(&Giant);
16533690Sphk	nanotime(&ats);
16682746Sdillon	mtx_unlock(&Giant);
167107849Salfred	return (copyout(&ats, uap->tp, sizeof(ats)));
16825583Speter}
16925583Speter
17025583Speter#ifndef _SYS_SYSPROTO_H_
17125583Speterstruct clock_settime_args {
17225583Speter	clockid_t clock_id;
17325583Speter	const struct	timespec *tp;
17425583Speter};
17525583Speter#endif
17625656Speter
17782746Sdillon/*
17882746Sdillon * MPSAFE
17982746Sdillon */
18025583Speter/* ARGSUSED */
18125583Speterint
182102074Sphkclock_settime(struct thread *td, struct clock_settime_args *uap)
18325583Speter{
18425583Speter	struct timeval atv;
18525583Speter	struct timespec ats;
18625583Speter	int error;
18725583Speter
188106369Srwatson#ifdef MAC
189106369Srwatson	error = mac_check_system_settime(td->td_ucred);
190106369Srwatson	if (error)
191106369Srwatson		return (error);
192106369Srwatson#endif
19393593Sjhb	if ((error = suser(td)) != 0)
19494343Sjhb		return (error);
195107849Salfred	if (uap->clock_id != CLOCK_REALTIME)
19694343Sjhb		return (EINVAL);
197107849Salfred	if ((error = copyin(uap->tp, &ats, sizeof(ats))) != 0)
19894343Sjhb		return (error);
19994343Sjhb	if (ats.tv_nsec < 0 || ats.tv_nsec >= 1000000000)
20094343Sjhb		return (EINVAL);
20134901Sphk	/* XXX Don't convert nsec->usec and back */
20225583Speter	TIMESPEC_TO_TIMEVAL(&atv, &ats);
20394343Sjhb	error = settime(td, &atv);
20482746Sdillon	return (error);
20525583Speter}
20625583Speter
20725583Speter#ifndef _SYS_SYSPROTO_H_
20825583Speterstruct clock_getres_args {
20925583Speter	clockid_t clock_id;
21025583Speter	struct	timespec *tp;
21125583Speter};
21225583Speter#endif
21325656Speter
21425583Speterint
215102074Sphkclock_getres(struct thread *td, struct clock_getres_args *uap)
21625583Speter{
21725583Speter	struct timespec ts;
21825656Speter	int error;
21925583Speter
220107849Salfred	if (uap->clock_id != CLOCK_REALTIME)
22125583Speter		return (EINVAL);
22225656Speter	error = 0;
223107849Salfred	if (uap->tp) {
22425583Speter		ts.tv_sec = 0;
225103964Sbde		/*
226103964Sbde		 * Round up the result of the division cheaply by adding 1.
227103964Sbde		 * Rounding up is especially important if rounding down
228103964Sbde		 * would give 0.  Perfect rounding is unimportant.
229103964Sbde		 */
230103964Sbde		ts.tv_nsec = 1000000000 / tc_getfrequency() + 1;
231107849Salfred		error = copyout(&ts, uap->tp, sizeof(ts));
23225583Speter	}
23325656Speter	return (error);
23425583Speter}
23525583Speter
23626335Speterstatic int nanowait;
23725656Speter
23826335Speterstatic int
239102074Sphknanosleep1(struct thread *td, struct timespec *rqt, struct timespec *rmt)
24025583Speter{
24135045Sphk	struct timespec ts, ts2, ts3;
24235042Sphk	struct timeval tv;
24335042Sphk	int error;
24425583Speter
24528773Sbde	if (rqt->tv_nsec < 0 || rqt->tv_nsec >= 1000000000)
24625656Speter		return (EINVAL);
24743301Sdillon	if (rqt->tv_sec < 0 || (rqt->tv_sec == 0 && rqt->tv_nsec == 0))
24828773Sbde		return (0);
24936119Sphk	getnanouptime(&ts);
25035029Sphk	timespecadd(&ts, rqt);
25135042Sphk	TIMESPEC_TO_TIMEVAL(&tv, rqt);
25235042Sphk	for (;;) {
25335042Sphk		error = tsleep(&nanowait, PWAIT | PCATCH, "nanslp",
25435042Sphk		    tvtohz(&tv));
25536119Sphk		getnanouptime(&ts2);
25635042Sphk		if (error != EWOULDBLOCK) {
25735042Sphk			if (error == ERESTART)
25835042Sphk				error = EINTR;
25935042Sphk			if (rmt != NULL) {
26035042Sphk				timespecsub(&ts, &ts2);
26135042Sphk				if (ts.tv_sec < 0)
26235042Sphk					timespecclear(&ts);
26335042Sphk				*rmt = ts;
26435042Sphk			}
26535042Sphk			return (error);
26635042Sphk		}
26735029Sphk		if (timespeccmp(&ts2, &ts, >=))
26835042Sphk			return (0);
26935045Sphk		ts3 = ts;
27035045Sphk		timespecsub(&ts3, &ts2);
27135045Sphk		TIMESPEC_TO_TIMEVAL(&tv, &ts3);
27226335Speter	}
27326335Speter}
27425583Speter
27526335Speter#ifndef _SYS_SYSPROTO_H_
27626335Speterstruct nanosleep_args {
27726335Speter	struct	timespec *rqtp;
27826335Speter	struct	timespec *rmtp;
27926335Speter};
28026335Speter#endif
28126335Speter
28282746Sdillon/*
28382746Sdillon * MPSAFE
28482746Sdillon */
28526335Speter/* ARGSUSED */
28626335Speterint
287102074Sphknanosleep(struct thread *td, struct nanosleep_args *uap)
28826335Speter{
28926335Speter	struct timespec rmt, rqt;
29082746Sdillon	int error;
29126335Speter
292107849Salfred	error = copyin(uap->rqtp, &rqt, sizeof(rqt));
29326335Speter	if (error)
29426335Speter		return (error);
29582746Sdillon
29682746Sdillon	mtx_lock(&Giant);
297107849Salfred	if (uap->rmtp) {
298107849Salfred		if (!useracc((caddr_t)uap->rmtp, sizeof(rmt),
29982746Sdillon		    VM_PROT_WRITE)) {
30082746Sdillon			error = EFAULT;
30182746Sdillon			goto done2;
30282746Sdillon		}
30382746Sdillon	}
30483366Sjulian	error = nanosleep1(td, &rqt, &rmt);
305107849Salfred	if (error && uap->rmtp) {
30682746Sdillon		int error2;
30782746Sdillon
308107849Salfred		error2 = copyout(&rmt, uap->rmtp, sizeof(rmt));
30926335Speter		if (error2)	/* XXX shouldn't happen, did useracc() above */
31082746Sdillon			error = error2;
31125583Speter	}
31282746Sdillondone2:
31382746Sdillon	mtx_unlock(&Giant);
31425656Speter	return (error);
31525583Speter}
31625583Speter
31726335Speter#ifndef _SYS_SYSPROTO_H_
3181541Srgrimesstruct gettimeofday_args {
3191541Srgrimes	struct	timeval *tp;
3201541Srgrimes	struct	timezone *tzp;
3211541Srgrimes};
32212221Sbde#endif
32382746Sdillon/*
32482746Sdillon * MPSAFE
32582746Sdillon */
3261541Srgrimes/* ARGSUSED */
3271549Srgrimesint
328102074Sphkgettimeofday(struct thread *td, struct gettimeofday_args *uap)
3291541Srgrimes{
3301541Srgrimes	struct timeval atv;
3311541Srgrimes	int error = 0;
3321541Srgrimes
3331541Srgrimes	if (uap->tp) {
3341541Srgrimes		microtime(&atv);
33599012Salfred		error = copyout(&atv, uap->tp, sizeof (atv));
3361541Srgrimes	}
33790836Sphk	if (error == 0 && uap->tzp != NULL) {
33890836Sphk		mtx_lock(&Giant);
33999012Salfred		error = copyout(&tz, uap->tzp, sizeof (tz));
34090836Sphk		mtx_unlock(&Giant);
34182746Sdillon	}
3421541Srgrimes	return (error);
3431541Srgrimes}
3441541Srgrimes
34512221Sbde#ifndef _SYS_SYSPROTO_H_
3461541Srgrimesstruct settimeofday_args {
3471541Srgrimes	struct	timeval *tv;
3481541Srgrimes	struct	timezone *tzp;
3491541Srgrimes};
35012221Sbde#endif
35182746Sdillon/*
35282746Sdillon * MPSAFE
35382746Sdillon */
3541541Srgrimes/* ARGSUSED */
3551549Srgrimesint
356102074Sphksettimeofday(struct thread *td, struct settimeofday_args *uap)
3571541Srgrimes{
35825656Speter	struct timeval atv;
3591541Srgrimes	struct timezone atz;
36082746Sdillon	int error = 0;
3611541Srgrimes
362106369Srwatson#ifdef MAC
363106369Srwatson	error = mac_check_system_settime(td->td_ucred);
364106369Srwatson	if (error)
365106369Srwatson		return (error);
366106369Srwatson#endif
36793593Sjhb	if ((error = suser(td)))
36894343Sjhb		return (error);
3691541Srgrimes	/* Verify all parameters before changing time. */
37025656Speter	if (uap->tv) {
37199012Salfred		if ((error = copyin(uap->tv, &atv, sizeof(atv))))
37294343Sjhb			return (error);
37394343Sjhb		if (atv.tv_usec < 0 || atv.tv_usec >= 1000000)
37494343Sjhb			return (EINVAL);
37525656Speter	}
3761541Srgrimes	if (uap->tzp &&
37799012Salfred	    (error = copyin(uap->tzp, &atz, sizeof(atz))))
37894343Sjhb		return (error);
37994343Sjhb
38094343Sjhb	if (uap->tv && (error = settime(td, &atv)))
38194343Sjhb		return (error);
38294343Sjhb	if (uap->tzp) {
38394343Sjhb		mtx_lock(&Giant);
38494343Sjhb		tz = atz;
38594343Sjhb		mtx_unlock(&Giant);
38682746Sdillon	}
38782746Sdillon	return (error);
3881541Srgrimes}
38982746Sdillon/*
3901541Srgrimes * Get value of an interval timer.  The process virtual and
3911541Srgrimes * profiling virtual time timers are kept in the p_stats area, since
3921541Srgrimes * they can be swapped out.  These are kept internally in the
3931541Srgrimes * way they are specified externally: in time until they expire.
3941541Srgrimes *
3951541Srgrimes * The real time interval timer is kept in the process table slot
3961541Srgrimes * for the process, and its value (it_value) is kept as an
3971541Srgrimes * absolute time rather than as a delta, so that it is easy to keep
3981541Srgrimes * periodic real-time signals from drifting.
3991541Srgrimes *
4001541Srgrimes * Virtual time timers are processed in the hardclock() routine of
4011541Srgrimes * kern_clock.c.  The real time timer is processed by a timeout
4021541Srgrimes * routine, called from the softclock() routine.  Since a callout
4031541Srgrimes * may be delayed in real time due to interrupt processing in the system,
4041541Srgrimes * it is possible for the real time timeout routine (realitexpire, given below),
4051541Srgrimes * to be delayed in real time past when it is supposed to occur.  It
4061541Srgrimes * does not suffice, therefore, to reload the real timer .it_value from the
4071541Srgrimes * real time timers .it_interval.  Rather, we compute the next time in
4081541Srgrimes * absolute time the timer should go off.
4091541Srgrimes */
41012221Sbde#ifndef _SYS_SYSPROTO_H_
4111541Srgrimesstruct getitimer_args {
4121541Srgrimes	u_int	which;
4131541Srgrimes	struct	itimerval *itv;
4141541Srgrimes};
41512221Sbde#endif
41682746Sdillon/*
41782746Sdillon * MPSAFE
41882746Sdillon */
4191541Srgrimes/* ARGSUSED */
4201549Srgrimesint
421102074Sphkgetitimer(struct thread *td, struct getitimer_args *uap)
4221541Srgrimes{
42383366Sjulian	struct proc *p = td->td_proc;
42434961Sphk	struct timeval ctv;
4251541Srgrimes	struct itimerval aitv;
4261541Srgrimes	int s;
42782746Sdillon	int error;
4281541Srgrimes
4291541Srgrimes	if (uap->which > ITIMER_PROF)
4301541Srgrimes		return (EINVAL);
43182746Sdillon
43282746Sdillon	mtx_lock(&Giant);
43382746Sdillon
43434961Sphk	s = splclock(); /* XXX still needed ? */
4351541Srgrimes	if (uap->which == ITIMER_REAL) {
4361541Srgrimes		/*
43736128Sbde		 * Convert from absolute to relative time in .it_value
4381541Srgrimes		 * part of real time timer.  If time for real time timer
4391541Srgrimes		 * has passed return 0, else return difference between
4401541Srgrimes		 * current time and time for the timer to go off.
4411541Srgrimes		 */
4421541Srgrimes		aitv = p->p_realtimer;
44335058Sphk		if (timevalisset(&aitv.it_value)) {
44436119Sphk			getmicrouptime(&ctv);
44535058Sphk			if (timevalcmp(&aitv.it_value, &ctv, <))
44635058Sphk				timevalclear(&aitv.it_value);
4471541Srgrimes			else
44834961Sphk				timevalsub(&aitv.it_value, &ctv);
44934961Sphk		}
45082746Sdillon	} else {
4511541Srgrimes		aitv = p->p_stats->p_timer[uap->which];
45282746Sdillon	}
4531541Srgrimes	splx(s);
45499012Salfred	error = copyout(&aitv, uap->itv, sizeof (struct itimerval));
45582746Sdillon	mtx_unlock(&Giant);
45682746Sdillon	return(error);
4571541Srgrimes}
4581541Srgrimes
45912221Sbde#ifndef _SYS_SYSPROTO_H_
4601541Srgrimesstruct setitimer_args {
4611541Srgrimes	u_int	which;
4621541Srgrimes	struct	itimerval *itv, *oitv;
4631541Srgrimes};
46412221Sbde#endif
46582746Sdillon/*
46682746Sdillon * MPSAFE
46782746Sdillon */
4681541Srgrimes/* ARGSUSED */
4691549Srgrimesint
470102074Sphksetitimer(struct thread *td, struct setitimer_args *uap)
4711541Srgrimes{
47283366Sjulian	struct proc *p = td->td_proc;
4731541Srgrimes	struct itimerval aitv;
47434961Sphk	struct timeval ctv;
475102074Sphk	struct itimerval *itvp;
47682746Sdillon	int s, error = 0;
4771541Srgrimes
4781541Srgrimes	if (uap->which > ITIMER_PROF)
4791541Srgrimes		return (EINVAL);
4801541Srgrimes	itvp = uap->itv;
48199012Salfred	if (itvp && (error = copyin(itvp, &aitv, sizeof(struct itimerval))))
4821541Srgrimes		return (error);
48382746Sdillon
48482746Sdillon	mtx_lock(&Giant);
48582746Sdillon
48612381Sbde	if ((uap->itv = uap->oitv) &&
48783366Sjulian	    (error = getitimer(td, (struct getitimer_args *)uap))) {
48882746Sdillon		goto done2;
48982746Sdillon	}
49082746Sdillon	if (itvp == 0) {
49182746Sdillon		error = 0;
49282746Sdillon		goto done2;
49382746Sdillon	}
49482746Sdillon	if (itimerfix(&aitv.it_value)) {
49582746Sdillon		error = EINVAL;
49682746Sdillon		goto done2;
49782746Sdillon	}
49882746Sdillon	if (!timevalisset(&aitv.it_value)) {
49935058Sphk		timevalclear(&aitv.it_interval);
50082746Sdillon	} else if (itimerfix(&aitv.it_interval)) {
50182746Sdillon		error = EINVAL;
50282746Sdillon		goto done2;
50382746Sdillon	}
50434961Sphk	s = splclock(); /* XXX: still needed ? */
5051541Srgrimes	if (uap->which == ITIMER_REAL) {
50635058Sphk		if (timevalisset(&p->p_realtimer.it_value))
50769286Sjake			callout_stop(&p->p_itcallout);
50835058Sphk		if (timevalisset(&aitv.it_value))
50969286Sjake			callout_reset(&p->p_itcallout, tvtohz(&aitv.it_value),
51069286Sjake			    realitexpire, p);
51136119Sphk		getmicrouptime(&ctv);
51235044Sphk		timevaladd(&aitv.it_value, &ctv);
5131541Srgrimes		p->p_realtimer = aitv;
51482746Sdillon	} else {
5151541Srgrimes		p->p_stats->p_timer[uap->which] = aitv;
51682746Sdillon	}
5171541Srgrimes	splx(s);
51882746Sdillondone2:
51982746Sdillon	mtx_unlock(&Giant);
52082746Sdillon	return (error);
5211541Srgrimes}
5221541Srgrimes
5231541Srgrimes/*
5241541Srgrimes * Real interval timer expired:
5251541Srgrimes * send process whose timer expired an alarm signal.
5261541Srgrimes * If time is not set up to reload, then just return.
5271541Srgrimes * Else compute next time timer should go off which is > current time.
5281541Srgrimes * This is where delay in processing this timeout causes multiple
5291541Srgrimes * SIGALRM calls to be compressed into one.
53036127Sbde * tvtohz() always adds 1 to allow for the time until the next clock
5319327Sbde * interrupt being strictly less than 1 clock tick, but we don't want
5329327Sbde * that here since we want to appear to be in sync with the clock
5339327Sbde * interrupt even when we're delayed.
5341541Srgrimes */
5351541Srgrimesvoid
536102074Sphkrealitexpire(void *arg)
5371541Srgrimes{
538102074Sphk	struct proc *p;
53935044Sphk	struct timeval ctv, ntv;
5401541Srgrimes	int s;
5411541Srgrimes
5421541Srgrimes	p = (struct proc *)arg;
54373916Sjhb	PROC_LOCK(p);
5441541Srgrimes	psignal(p, SIGALRM);
54535058Sphk	if (!timevalisset(&p->p_realtimer.it_interval)) {
54635058Sphk		timevalclear(&p->p_realtimer.it_value);
54773916Sjhb		PROC_UNLOCK(p);
5481541Srgrimes		return;
5491541Srgrimes	}
5501541Srgrimes	for (;;) {
55134961Sphk		s = splclock(); /* XXX: still neeeded ? */
5521541Srgrimes		timevaladd(&p->p_realtimer.it_value,
5531541Srgrimes		    &p->p_realtimer.it_interval);
55436119Sphk		getmicrouptime(&ctv);
55535058Sphk		if (timevalcmp(&p->p_realtimer.it_value, &ctv, >)) {
55635044Sphk			ntv = p->p_realtimer.it_value;
55735044Sphk			timevalsub(&ntv, &ctv);
55869286Sjake			callout_reset(&p->p_itcallout, tvtohz(&ntv) - 1,
55969286Sjake			    realitexpire, p);
5601541Srgrimes			splx(s);
56173916Sjhb			PROC_UNLOCK(p);
5621541Srgrimes			return;
5631541Srgrimes		}
5641541Srgrimes		splx(s);
5651541Srgrimes	}
56673916Sjhb	/*NOTREACHED*/
5671541Srgrimes}
5681541Srgrimes
5691541Srgrimes/*
5701541Srgrimes * Check that a proposed value to load into the .it_value or
5711541Srgrimes * .it_interval part of an interval timer is acceptable, and
5721541Srgrimes * fix it to have at least minimal value (i.e. if it is less
5731541Srgrimes * than the resolution of the clock, round it up.)
5741541Srgrimes */
5751549Srgrimesint
576102074Sphkitimerfix(struct timeval *tv)
5771541Srgrimes{
5781541Srgrimes
5791541Srgrimes	if (tv->tv_sec < 0 || tv->tv_sec > 100000000 ||
5801541Srgrimes	    tv->tv_usec < 0 || tv->tv_usec >= 1000000)
5811541Srgrimes		return (EINVAL);
5821541Srgrimes	if (tv->tv_sec == 0 && tv->tv_usec != 0 && tv->tv_usec < tick)
5831541Srgrimes		tv->tv_usec = tick;
5841541Srgrimes	return (0);
5851541Srgrimes}
5861541Srgrimes
5871541Srgrimes/*
5881541Srgrimes * Decrement an interval timer by a specified number
5891541Srgrimes * of microseconds, which must be less than a second,
5901541Srgrimes * i.e. < 1000000.  If the timer expires, then reload
5911541Srgrimes * it.  In this case, carry over (usec - old value) to
5921541Srgrimes * reduce the value reloaded into the timer so that
5931541Srgrimes * the timer does not drift.  This routine assumes
5941541Srgrimes * that it is called in a context where the timers
5951541Srgrimes * on which it is operating cannot change in value.
5961541Srgrimes */
5971549Srgrimesint
598102074Sphkitimerdecr(struct itimerval *itp, int usec)
5991541Srgrimes{
6001541Srgrimes
6011541Srgrimes	if (itp->it_value.tv_usec < usec) {
6021541Srgrimes		if (itp->it_value.tv_sec == 0) {
6031541Srgrimes			/* expired, and already in next interval */
6041541Srgrimes			usec -= itp->it_value.tv_usec;
6051541Srgrimes			goto expire;
6061541Srgrimes		}
6071541Srgrimes		itp->it_value.tv_usec += 1000000;
6081541Srgrimes		itp->it_value.tv_sec--;
6091541Srgrimes	}
6101541Srgrimes	itp->it_value.tv_usec -= usec;
6111541Srgrimes	usec = 0;
61235058Sphk	if (timevalisset(&itp->it_value))
6131541Srgrimes		return (1);
6141541Srgrimes	/* expired, exactly at end of interval */
6151541Srgrimesexpire:
61635058Sphk	if (timevalisset(&itp->it_interval)) {
6171541Srgrimes		itp->it_value = itp->it_interval;
6181541Srgrimes		itp->it_value.tv_usec -= usec;
6191541Srgrimes		if (itp->it_value.tv_usec < 0) {
6201541Srgrimes			itp->it_value.tv_usec += 1000000;
6211541Srgrimes			itp->it_value.tv_sec--;
6221541Srgrimes		}
6231541Srgrimes	} else
6241541Srgrimes		itp->it_value.tv_usec = 0;		/* sec is already 0 */
6251541Srgrimes	return (0);
6261541Srgrimes}
6271541Srgrimes
6281541Srgrimes/*
6291541Srgrimes * Add and subtract routines for timevals.
6301541Srgrimes * N.B.: subtract routine doesn't deal with
6311541Srgrimes * results which are before the beginning,
6321541Srgrimes * it just gets very confused in this case.
6331541Srgrimes * Caveat emptor.
6341541Srgrimes */
6351549Srgrimesvoid
636102074Sphktimevaladd(struct timeval *t1, struct timeval *t2)
6371541Srgrimes{
6381541Srgrimes
6391541Srgrimes	t1->tv_sec += t2->tv_sec;
6401541Srgrimes	t1->tv_usec += t2->tv_usec;
6411541Srgrimes	timevalfix(t1);
6421541Srgrimes}
6431541Srgrimes
6441549Srgrimesvoid
645102074Sphktimevalsub(struct timeval *t1, struct timeval *t2)
6461541Srgrimes{
6471541Srgrimes
6481541Srgrimes	t1->tv_sec -= t2->tv_sec;
6491541Srgrimes	t1->tv_usec -= t2->tv_usec;
6501541Srgrimes	timevalfix(t1);
6511541Srgrimes}
6521541Srgrimes
65312819Sphkstatic void
654102074Sphktimevalfix(struct timeval *t1)
6551541Srgrimes{
6561541Srgrimes
6571541Srgrimes	if (t1->tv_usec < 0) {
6581541Srgrimes		t1->tv_sec--;
6591541Srgrimes		t1->tv_usec += 1000000;
6601541Srgrimes	}
6611541Srgrimes	if (t1->tv_usec >= 1000000) {
6621541Srgrimes		t1->tv_sec++;
6631541Srgrimes		t1->tv_usec -= 1000000;
6641541Srgrimes	}
6651541Srgrimes}
666108142Ssam
667108142Ssam/*
668108511Ssam * ratecheck(): simple time-based rate-limit checking.
669108142Ssam */
670108142Ssamint
671108142Ssamratecheck(struct timeval *lasttime, const struct timeval *mininterval)
672108142Ssam{
673108142Ssam	struct timeval tv, delta;
674108142Ssam	int rv = 0;
675108142Ssam
676108511Ssam	getmicrouptime(&tv);		/* NB: 10ms precision */
677108511Ssam	delta = tv;
678108511Ssam	timevalsub(&delta, lasttime);
679108142Ssam
680108142Ssam	/*
681108142Ssam	 * check for 0,0 is so that the message will be seen at least once,
682108142Ssam	 * even if interval is huge.
683108142Ssam	 */
684108142Ssam	if (timevalcmp(&delta, mininterval, >=) ||
685108142Ssam	    (lasttime->tv_sec == 0 && lasttime->tv_usec == 0)) {
686108142Ssam		*lasttime = tv;
687108142Ssam		rv = 1;
688108142Ssam	}
689108142Ssam
690108142Ssam	return (rv);
691108142Ssam}
692108142Ssam
693108142Ssam/*
694108142Ssam * ppsratecheck(): packets (or events) per second limitation.
695108511Ssam *
696108511Ssam * Return 0 if the limit is to be enforced (e.g. the caller
697108511Ssam * should drop a packet because of the rate limitation).
698108511Ssam *
699108511Ssam * Note that we maintain the struct timeval for compatibility
700108511Ssam * with other bsd systems.  We reuse the storage and just monitor
701108511Ssam * clock ticks for minimal overhead.
702108142Ssam */
703108142Ssamint
704108142Ssamppsratecheck(struct timeval *lasttime, int *curpps, int maxpps)
705108142Ssam{
706108511Ssam	int now;
707108142Ssam
708108142Ssam	/*
709108511Ssam	 * Reset the last time and counter if this is the first call
710108511Ssam	 * or more than a second has passed since the last update of
711108511Ssam	 * lasttime.
712108142Ssam	 */
713108511Ssam	now = ticks;
714108511Ssam	if (lasttime->tv_sec == 0 || (u_int)(now - lasttime->tv_sec) >= hz) {
715108511Ssam		lasttime->tv_sec = now;
716108511Ssam		*curpps = 1;
717108511Ssam		return (1);
718108511Ssam	} else {
719108511Ssam		(*curpps)++;		/* NB: ignore potential overflow */
720108511Ssam		return (maxpps < 0 || *curpps < maxpps);
721108511Ssam	}
722108142Ssam}
723