kern_time.c revision 139804
1139804Simp/*-
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 * 4. Neither the name of the University nor the names of its contributors
141541Srgrimes *    may be used to endorse or promote products derived from this software
151541Srgrimes *    without specific prior written permission.
161541Srgrimes *
171541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
181541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
191541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
201541Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
211541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
221541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
231541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
241541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
251541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
261541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
271541Srgrimes * SUCH DAMAGE.
281541Srgrimes *
291541Srgrimes *	@(#)kern_time.c	8.1 (Berkeley) 6/10/93
301541Srgrimes */
311541Srgrimes
32116182Sobrien#include <sys/cdefs.h>
33116182Sobrien__FBSDID("$FreeBSD: head/sys/kern/kern_time.c 139804 2005-01-06 23:35:40Z imp $");
34116182Sobrien
35106369Srwatson#include "opt_mac.h"
36106369Srwatson
371541Srgrimes#include <sys/param.h>
3848274Speter#include <sys/systm.h>
3976166Smarkm#include <sys/lock.h>
4076166Smarkm#include <sys/mutex.h>
4112221Sbde#include <sys/sysproto.h>
421541Srgrimes#include <sys/resourcevar.h>
433308Sphk#include <sys/signalvar.h>
441541Srgrimes#include <sys/kernel.h>
45106369Srwatson#include <sys/mac.h>
4625583Speter#include <sys/sysent.h>
471541Srgrimes#include <sys/proc.h>
4825656Speter#include <sys/time.h>
4958377Sphk#include <sys/timetc.h>
501541Srgrimes#include <sys/vnode.h>
5176166Smarkm
5226335Speter#include <vm/vm.h>
5326335Speter#include <vm/vm_extern.h>
541541Srgrimes
55110299Sphkint tz_minuteswest;
56110299Sphkint tz_dsttime;
579369Sdg
588876Srgrimes/*
591541Srgrimes * Time of day and interval timer support.
601541Srgrimes *
611541Srgrimes * These routines provide the kernel entry points to get and set
621541Srgrimes * the time-of-day and per-process interval timers.  Subroutines
631541Srgrimes * here provide support for adding and subtracting timeval structures
641541Srgrimes * and decrementing interval timers, optionally reloading the interval
651541Srgrimes * timers when they expire.
661541Srgrimes */
671541Srgrimes
6892723Salfredstatic int	nanosleep1(struct thread *td, struct timespec *rqt,
6992723Salfred		    struct timespec *rmt);
7094343Sjhbstatic int	settime(struct thread *, struct timeval *);
7192723Salfredstatic void	timevalfix(struct timeval *);
7292723Salfredstatic void	no_lease_updatetime(int);
7313016Sbde
7430739Sphkstatic void
7530739Sphkno_lease_updatetime(deltat)
7630739Sphk	int deltat;
7730739Sphk{
7830739Sphk}
7930739Sphk
8092723Salfredvoid (*lease_updatetime)(int)  = no_lease_updatetime;
8130739Sphk
8225583Speterstatic int
83102074Sphksettime(struct thread *td, struct timeval *tv)
8425583Speter{
8545433Snsayer	struct timeval delta, tv1, tv2;
8645438Snsayer	static struct timeval maxtime, laststep;
8733690Sphk	struct timespec ts;
8825583Speter	int s;
8925583Speter
9025656Speter	s = splclock();
9133818Sbde	microtime(&tv1);
9235029Sphk	delta = *tv;
9335029Sphk	timevalsub(&delta, &tv1);
9425583Speter
9525583Speter	/*
9633818Sbde	 * If the system is secure, we do not allow the time to be
9745433Snsayer	 * set to a value earlier than 1 second less than the highest
9845433Snsayer	 * time we have yet seen. The worst a miscreant can do in
9945433Snsayer	 * this circumstance is "freeze" time. He couldn't go
10045433Snsayer	 * back to the past.
10145438Snsayer	 *
10245438Snsayer	 * We similarly do not allow the clock to be stepped more
10345438Snsayer	 * than one second, nor more than once per second. This allows
10445438Snsayer	 * a miscreant to make the clock march double-time, but no worse.
10525583Speter	 */
10694343Sjhb	if (securelevel_gt(td->td_ucred, 1) != 0) {
10745433Snsayer		if (delta.tv_sec < 0 || delta.tv_usec < 0) {
10845437Smjacob			/*
10945438Snsayer			 * Update maxtime to latest time we've seen.
11045437Smjacob			 */
11145437Smjacob			if (tv1.tv_sec > maxtime.tv_sec)
11245437Smjacob				maxtime = tv1;
11345437Smjacob			tv2 = *tv;
11445437Smjacob			timevalsub(&tv2, &maxtime);
11545437Smjacob			if (tv2.tv_sec < -1) {
11645437Smjacob				tv->tv_sec = maxtime.tv_sec - 1;
11745433Snsayer				printf("Time adjustment clamped to -1 second\n");
11845433Snsayer			}
11945437Smjacob		} else {
12045438Snsayer			if (tv1.tv_sec == laststep.tv_sec) {
12145438Snsayer				splx(s);
12245438Snsayer				return (EPERM);
12345438Snsayer			}
12445438Snsayer			if (delta.tv_sec > 1) {
12545438Snsayer				tv->tv_sec = tv1.tv_sec + 1;
12645438Snsayer				printf("Time adjustment clamped to +1 second\n");
12745438Snsayer			}
12845438Snsayer			laststep = *tv;
12945433Snsayer		}
13033818Sbde	}
13133818Sbde
13233690Sphk	ts.tv_sec = tv->tv_sec;
13333690Sphk	ts.tv_nsec = tv->tv_usec * 1000;
13494343Sjhb	mtx_lock(&Giant);
13558377Sphk	tc_setclock(&ts);
13625583Speter	(void) splsoftclock();
13725583Speter	lease_updatetime(delta.tv_sec);
13825583Speter	splx(s);
13925583Speter	resettodr();
14094343Sjhb	mtx_unlock(&Giant);
14125583Speter	return (0);
14225583Speter}
14325583Speter
14412221Sbde#ifndef _SYS_SYSPROTO_H_
14525583Speterstruct clock_gettime_args {
14625583Speter	clockid_t clock_id;
14725583Speter	struct	timespec *tp;
14825583Speter};
14925583Speter#endif
15025656Speter
15182746Sdillon/*
15282746Sdillon * MPSAFE
15382746Sdillon */
15425583Speter/* ARGSUSED */
15525583Speterint
156102074Sphkclock_gettime(struct thread *td, struct clock_gettime_args *uap)
15725583Speter{
15825583Speter	struct timespec ats;
159130884Skbyanc	struct timeval sys, user;
160136152Sjhb	struct proc *p;
16125583Speter
162136152Sjhb	p = td->td_proc;
163130654Skbyanc	switch (uap->clock_id) {
164130654Skbyanc	case CLOCK_REALTIME:
165111300Sphk		nanotime(&ats);
166130654Skbyanc		break;
167130654Skbyanc	case CLOCK_VIRTUAL:
168136152Sjhb		PROC_LOCK(p);
169136152Sjhb		calcru(p, &user, &sys);
170136152Sjhb		PROC_UNLOCK(p);
171130654Skbyanc		TIMEVAL_TO_TIMESPEC(&user, &ats);
172130654Skbyanc		break;
173130654Skbyanc	case CLOCK_PROF:
174136152Sjhb		PROC_LOCK(p);
175136152Sjhb		calcru(p, &user, &sys);
176136152Sjhb		PROC_UNLOCK(p);
177130884Skbyanc		timevaladd(&user, &sys);
178130884Skbyanc		TIMEVAL_TO_TIMESPEC(&user, &ats);
179130654Skbyanc		break;
180130884Skbyanc	case CLOCK_MONOTONIC:
181130884Skbyanc		nanouptime(&ats);
182130884Skbyanc		break;
183130654Skbyanc	default:
184111315Sphk		return (EINVAL);
185130654Skbyanc	}
186107849Salfred	return (copyout(&ats, uap->tp, sizeof(ats)));
18725583Speter}
18825583Speter
18925583Speter#ifndef _SYS_SYSPROTO_H_
19025583Speterstruct clock_settime_args {
19125583Speter	clockid_t clock_id;
19225583Speter	const struct	timespec *tp;
19325583Speter};
19425583Speter#endif
19525656Speter
19682746Sdillon/*
19782746Sdillon * MPSAFE
19882746Sdillon */
19925583Speter/* ARGSUSED */
20025583Speterint
201102074Sphkclock_settime(struct thread *td, struct clock_settime_args *uap)
20225583Speter{
20325583Speter	struct timeval atv;
20425583Speter	struct timespec ats;
20525583Speter	int error;
20625583Speter
207106369Srwatson#ifdef MAC
208106369Srwatson	error = mac_check_system_settime(td->td_ucred);
209106369Srwatson	if (error)
210106369Srwatson		return (error);
211106369Srwatson#endif
21293593Sjhb	if ((error = suser(td)) != 0)
21394343Sjhb		return (error);
214107849Salfred	if (uap->clock_id != CLOCK_REALTIME)
21594343Sjhb		return (EINVAL);
216107849Salfred	if ((error = copyin(uap->tp, &ats, sizeof(ats))) != 0)
21794343Sjhb		return (error);
21894343Sjhb	if (ats.tv_nsec < 0 || ats.tv_nsec >= 1000000000)
21994343Sjhb		return (EINVAL);
22034901Sphk	/* XXX Don't convert nsec->usec and back */
22125583Speter	TIMESPEC_TO_TIMEVAL(&atv, &ats);
22294343Sjhb	error = settime(td, &atv);
22382746Sdillon	return (error);
22425583Speter}
22525583Speter
22625583Speter#ifndef _SYS_SYSPROTO_H_
22725583Speterstruct clock_getres_args {
22825583Speter	clockid_t clock_id;
22925583Speter	struct	timespec *tp;
23025583Speter};
23125583Speter#endif
23225656Speter
23325583Speterint
234102074Sphkclock_getres(struct thread *td, struct clock_getres_args *uap)
23525583Speter{
23625583Speter	struct timespec ts;
23725583Speter
238130654Skbyanc	ts.tv_sec = 0;
239130654Skbyanc	switch (uap->clock_id) {
240130654Skbyanc	case CLOCK_REALTIME:
241130654Skbyanc	case CLOCK_MONOTONIC:
242103964Sbde		/*
243103964Sbde		 * Round up the result of the division cheaply by adding 1.
244103964Sbde		 * Rounding up is especially important if rounding down
245103964Sbde		 * would give 0.  Perfect rounding is unimportant.
246103964Sbde		 */
247103964Sbde		ts.tv_nsec = 1000000000 / tc_getfrequency() + 1;
248130654Skbyanc		break;
249130654Skbyanc	case CLOCK_VIRTUAL:
250130654Skbyanc	case CLOCK_PROF:
251130654Skbyanc		/* Accurately round up here because we can do so cheaply. */
252130654Skbyanc		ts.tv_nsec = (1000000000 + hz - 1) / hz;
253130654Skbyanc		break;
254130654Skbyanc	default:
255130654Skbyanc		return (EINVAL);
256130654Skbyanc	}
257130884Skbyanc	if (uap->tp == NULL)
258130884Skbyanc		return (0);
259130884Skbyanc	return (copyout(&ts, uap->tp, sizeof(ts)));
26025583Speter}
26125583Speter
26226335Speterstatic int nanowait;
26325656Speter
26426335Speterstatic int
265102074Sphknanosleep1(struct thread *td, struct timespec *rqt, struct timespec *rmt)
26625583Speter{
26735045Sphk	struct timespec ts, ts2, ts3;
26835042Sphk	struct timeval tv;
26935042Sphk	int error;
27025583Speter
27128773Sbde	if (rqt->tv_nsec < 0 || rqt->tv_nsec >= 1000000000)
27225656Speter		return (EINVAL);
27343301Sdillon	if (rqt->tv_sec < 0 || (rqt->tv_sec == 0 && rqt->tv_nsec == 0))
27428773Sbde		return (0);
27536119Sphk	getnanouptime(&ts);
27635029Sphk	timespecadd(&ts, rqt);
27735042Sphk	TIMESPEC_TO_TIMEVAL(&tv, rqt);
27835042Sphk	for (;;) {
27935042Sphk		error = tsleep(&nanowait, PWAIT | PCATCH, "nanslp",
28035042Sphk		    tvtohz(&tv));
28136119Sphk		getnanouptime(&ts2);
28235042Sphk		if (error != EWOULDBLOCK) {
28335042Sphk			if (error == ERESTART)
28435042Sphk				error = EINTR;
28535042Sphk			if (rmt != NULL) {
28635042Sphk				timespecsub(&ts, &ts2);
28735042Sphk				if (ts.tv_sec < 0)
28835042Sphk					timespecclear(&ts);
28935042Sphk				*rmt = ts;
29035042Sphk			}
29135042Sphk			return (error);
29235042Sphk		}
29335029Sphk		if (timespeccmp(&ts2, &ts, >=))
29435042Sphk			return (0);
29535045Sphk		ts3 = ts;
29635045Sphk		timespecsub(&ts3, &ts2);
29735045Sphk		TIMESPEC_TO_TIMEVAL(&tv, &ts3);
29826335Speter	}
29926335Speter}
30025583Speter
30126335Speter#ifndef _SYS_SYSPROTO_H_
30226335Speterstruct nanosleep_args {
30326335Speter	struct	timespec *rqtp;
30426335Speter	struct	timespec *rmtp;
30526335Speter};
30626335Speter#endif
30726335Speter
30882746Sdillon/*
30982746Sdillon * MPSAFE
31082746Sdillon */
31126335Speter/* ARGSUSED */
31226335Speterint
313102074Sphknanosleep(struct thread *td, struct nanosleep_args *uap)
31426335Speter{
31526335Speter	struct timespec rmt, rqt;
31682746Sdillon	int error;
31726335Speter
318107849Salfred	error = copyin(uap->rqtp, &rqt, sizeof(rqt));
31926335Speter	if (error)
32026335Speter		return (error);
32182746Sdillon
322109521Salfred	if (uap->rmtp &&
323109521Salfred	    !useracc((caddr_t)uap->rmtp, sizeof(rmt), VM_PROT_WRITE))
324109521Salfred			return (EFAULT);
32583366Sjulian	error = nanosleep1(td, &rqt, &rmt);
326107849Salfred	if (error && uap->rmtp) {
32782746Sdillon		int error2;
32882746Sdillon
329107849Salfred		error2 = copyout(&rmt, uap->rmtp, sizeof(rmt));
330109521Salfred		if (error2)
33182746Sdillon			error = error2;
33225583Speter	}
33325656Speter	return (error);
33425583Speter}
33525583Speter
33626335Speter#ifndef _SYS_SYSPROTO_H_
3371541Srgrimesstruct gettimeofday_args {
3381541Srgrimes	struct	timeval *tp;
3391541Srgrimes	struct	timezone *tzp;
3401541Srgrimes};
34112221Sbde#endif
34282746Sdillon/*
34382746Sdillon * MPSAFE
34482746Sdillon */
3451541Srgrimes/* ARGSUSED */
3461549Srgrimesint
347102074Sphkgettimeofday(struct thread *td, struct gettimeofday_args *uap)
3481541Srgrimes{
3491541Srgrimes	struct timeval atv;
350110286Stjr	struct timezone rtz;
3511541Srgrimes	int error = 0;
3521541Srgrimes
3531541Srgrimes	if (uap->tp) {
3541541Srgrimes		microtime(&atv);
35599012Salfred		error = copyout(&atv, uap->tp, sizeof (atv));
3561541Srgrimes	}
35790836Sphk	if (error == 0 && uap->tzp != NULL) {
358110299Sphk		rtz.tz_minuteswest = tz_minuteswest;
359110299Sphk		rtz.tz_dsttime = tz_dsttime;
360110286Stjr		error = copyout(&rtz, uap->tzp, sizeof (rtz));
36182746Sdillon	}
3621541Srgrimes	return (error);
3631541Srgrimes}
3641541Srgrimes
36512221Sbde#ifndef _SYS_SYSPROTO_H_
3661541Srgrimesstruct settimeofday_args {
3671541Srgrimes	struct	timeval *tv;
3681541Srgrimes	struct	timezone *tzp;
3691541Srgrimes};
37012221Sbde#endif
37182746Sdillon/*
37282746Sdillon * MPSAFE
37382746Sdillon */
3741541Srgrimes/* ARGSUSED */
3751549Srgrimesint
376102074Sphksettimeofday(struct thread *td, struct settimeofday_args *uap)
3771541Srgrimes{
37825656Speter	struct timeval atv;
3791541Srgrimes	struct timezone atz;
38082746Sdillon	int error = 0;
3811541Srgrimes
382106369Srwatson#ifdef MAC
383106369Srwatson	error = mac_check_system_settime(td->td_ucred);
384106369Srwatson	if (error)
385106369Srwatson		return (error);
386106369Srwatson#endif
38793593Sjhb	if ((error = suser(td)))
38894343Sjhb		return (error);
3891541Srgrimes	/* Verify all parameters before changing time. */
39025656Speter	if (uap->tv) {
39199012Salfred		if ((error = copyin(uap->tv, &atv, sizeof(atv))))
39294343Sjhb			return (error);
39394343Sjhb		if (atv.tv_usec < 0 || atv.tv_usec >= 1000000)
39494343Sjhb			return (EINVAL);
39525656Speter	}
3961541Srgrimes	if (uap->tzp &&
39799012Salfred	    (error = copyin(uap->tzp, &atz, sizeof(atz))))
39894343Sjhb		return (error);
39994343Sjhb
40094343Sjhb	if (uap->tv && (error = settime(td, &atv)))
40194343Sjhb		return (error);
40294343Sjhb	if (uap->tzp) {
403110299Sphk		tz_minuteswest = atz.tz_minuteswest;
404110299Sphk		tz_dsttime = atz.tz_dsttime;
40582746Sdillon	}
40682746Sdillon	return (error);
4071541Srgrimes}
40882746Sdillon/*
4091541Srgrimes * Get value of an interval timer.  The process virtual and
4101541Srgrimes * profiling virtual time timers are kept in the p_stats area, since
4111541Srgrimes * they can be swapped out.  These are kept internally in the
4121541Srgrimes * way they are specified externally: in time until they expire.
4131541Srgrimes *
4141541Srgrimes * The real time interval timer is kept in the process table slot
4151541Srgrimes * for the process, and its value (it_value) is kept as an
4161541Srgrimes * absolute time rather than as a delta, so that it is easy to keep
4171541Srgrimes * periodic real-time signals from drifting.
4181541Srgrimes *
4191541Srgrimes * Virtual time timers are processed in the hardclock() routine of
4201541Srgrimes * kern_clock.c.  The real time timer is processed by a timeout
4211541Srgrimes * routine, called from the softclock() routine.  Since a callout
4221541Srgrimes * may be delayed in real time due to interrupt processing in the system,
4231541Srgrimes * it is possible for the real time timeout routine (realitexpire, given below),
4241541Srgrimes * to be delayed in real time past when it is supposed to occur.  It
4251541Srgrimes * does not suffice, therefore, to reload the real timer .it_value from the
4261541Srgrimes * real time timers .it_interval.  Rather, we compute the next time in
4271541Srgrimes * absolute time the timer should go off.
4281541Srgrimes */
42912221Sbde#ifndef _SYS_SYSPROTO_H_
4301541Srgrimesstruct getitimer_args {
4311541Srgrimes	u_int	which;
4321541Srgrimes	struct	itimerval *itv;
4331541Srgrimes};
43412221Sbde#endif
43582746Sdillon/*
43682746Sdillon * MPSAFE
43782746Sdillon */
4381549Srgrimesint
439102074Sphkgetitimer(struct thread *td, struct getitimer_args *uap)
4401541Srgrimes{
44183366Sjulian	struct proc *p = td->td_proc;
44234961Sphk	struct timeval ctv;
4431541Srgrimes	struct itimerval aitv;
4441541Srgrimes
4451541Srgrimes	if (uap->which > ITIMER_PROF)
4461541Srgrimes		return (EINVAL);
44782746Sdillon
4481541Srgrimes	if (uap->which == ITIMER_REAL) {
4491541Srgrimes		/*
45036128Sbde		 * Convert from absolute to relative time in .it_value
4511541Srgrimes		 * part of real time timer.  If time for real time timer
4521541Srgrimes		 * has passed return 0, else return difference between
4531541Srgrimes		 * current time and time for the timer to go off.
4541541Srgrimes		 */
455111034Stjr		PROC_LOCK(p);
4561541Srgrimes		aitv = p->p_realtimer;
457111034Stjr		PROC_UNLOCK(p);
45835058Sphk		if (timevalisset(&aitv.it_value)) {
45936119Sphk			getmicrouptime(&ctv);
46035058Sphk			if (timevalcmp(&aitv.it_value, &ctv, <))
46135058Sphk				timevalclear(&aitv.it_value);
4621541Srgrimes			else
46334961Sphk				timevalsub(&aitv.it_value, &ctv);
46434961Sphk		}
46582746Sdillon	} else {
466111034Stjr		mtx_lock_spin(&sched_lock);
4671541Srgrimes		aitv = p->p_stats->p_timer[uap->which];
468111034Stjr		mtx_unlock_spin(&sched_lock);
46982746Sdillon	}
470110286Stjr	return (copyout(&aitv, uap->itv, sizeof (struct itimerval)));
4711541Srgrimes}
4721541Srgrimes
47312221Sbde#ifndef _SYS_SYSPROTO_H_
4741541Srgrimesstruct setitimer_args {
4751541Srgrimes	u_int	which;
4761541Srgrimes	struct	itimerval *itv, *oitv;
4771541Srgrimes};
47812221Sbde#endif
47982746Sdillon/*
48082746Sdillon * MPSAFE
48182746Sdillon */
4821549Srgrimesint
483102074Sphksetitimer(struct thread *td, struct setitimer_args *uap)
4841541Srgrimes{
48583366Sjulian	struct proc *p = td->td_proc;
486111034Stjr	struct itimerval aitv, oitv;
48734961Sphk	struct timeval ctv;
488111034Stjr	int error;
4891541Srgrimes
490111034Stjr	if (uap->itv == NULL) {
491111034Stjr		uap->itv = uap->oitv;
492111034Stjr		return (getitimer(td, (struct getitimer_args *)uap));
493111034Stjr	}
494111034Stjr
4951541Srgrimes	if (uap->which > ITIMER_PROF)
4961541Srgrimes		return (EINVAL);
497111034Stjr	if ((error = copyin(uap->itv, &aitv, sizeof(struct itimerval))))
4981541Srgrimes		return (error);
499111034Stjr	if (itimerfix(&aitv.it_value))
500111034Stjr		return (EINVAL);
501111034Stjr	if (!timevalisset(&aitv.it_value))
502111034Stjr		timevalclear(&aitv.it_interval);
503111034Stjr	else if (itimerfix(&aitv.it_interval))
504111034Stjr		return (EINVAL);
50582746Sdillon
5061541Srgrimes	if (uap->which == ITIMER_REAL) {
507111034Stjr		PROC_LOCK(p);
50835058Sphk		if (timevalisset(&p->p_realtimer.it_value))
50969286Sjake			callout_stop(&p->p_itcallout);
510114980Sjhb		getmicrouptime(&ctv);
511114980Sjhb		if (timevalisset(&aitv.it_value)) {
51269286Sjake			callout_reset(&p->p_itcallout, tvtohz(&aitv.it_value),
51369286Sjake			    realitexpire, p);
514114980Sjhb			timevaladd(&aitv.it_value, &ctv);
515114980Sjhb		}
516111034Stjr		oitv = p->p_realtimer;
5171541Srgrimes		p->p_realtimer = aitv;
518111034Stjr		PROC_UNLOCK(p);
519111034Stjr		if (timevalisset(&oitv.it_value)) {
520111034Stjr			if (timevalcmp(&oitv.it_value, &ctv, <))
521111034Stjr				timevalclear(&oitv.it_value);
522111034Stjr			else
523111034Stjr				timevalsub(&oitv.it_value, &ctv);
524111034Stjr		}
52582746Sdillon	} else {
526111034Stjr		mtx_lock_spin(&sched_lock);
527111034Stjr		oitv = p->p_stats->p_timer[uap->which];
5281541Srgrimes		p->p_stats->p_timer[uap->which] = aitv;
529111034Stjr		mtx_unlock_spin(&sched_lock);
53082746Sdillon	}
531111034Stjr	if (uap->oitv == NULL)
532111034Stjr		return (0);
533111034Stjr	return (copyout(&oitv, uap->oitv, sizeof(struct itimerval)));
5341541Srgrimes}
5351541Srgrimes
5361541Srgrimes/*
5371541Srgrimes * Real interval timer expired:
5381541Srgrimes * send process whose timer expired an alarm signal.
5391541Srgrimes * If time is not set up to reload, then just return.
5401541Srgrimes * Else compute next time timer should go off which is > current time.
5411541Srgrimes * This is where delay in processing this timeout causes multiple
5421541Srgrimes * SIGALRM calls to be compressed into one.
54336127Sbde * tvtohz() always adds 1 to allow for the time until the next clock
5449327Sbde * interrupt being strictly less than 1 clock tick, but we don't want
5459327Sbde * that here since we want to appear to be in sync with the clock
5469327Sbde * interrupt even when we're delayed.
5471541Srgrimes */
5481541Srgrimesvoid
549102074Sphkrealitexpire(void *arg)
5501541Srgrimes{
551102074Sphk	struct proc *p;
55235044Sphk	struct timeval ctv, ntv;
5531541Srgrimes
5541541Srgrimes	p = (struct proc *)arg;
55573916Sjhb	PROC_LOCK(p);
5561541Srgrimes	psignal(p, SIGALRM);
55735058Sphk	if (!timevalisset(&p->p_realtimer.it_interval)) {
55835058Sphk		timevalclear(&p->p_realtimer.it_value);
559116123Sjhb		if (p->p_flag & P_WEXIT)
560116123Sjhb			wakeup(&p->p_itcallout);
56173916Sjhb		PROC_UNLOCK(p);
5621541Srgrimes		return;
5631541Srgrimes	}
5641541Srgrimes	for (;;) {
5651541Srgrimes		timevaladd(&p->p_realtimer.it_value,
5661541Srgrimes		    &p->p_realtimer.it_interval);
56736119Sphk		getmicrouptime(&ctv);
56835058Sphk		if (timevalcmp(&p->p_realtimer.it_value, &ctv, >)) {
56935044Sphk			ntv = p->p_realtimer.it_value;
57035044Sphk			timevalsub(&ntv, &ctv);
57169286Sjake			callout_reset(&p->p_itcallout, tvtohz(&ntv) - 1,
57269286Sjake			    realitexpire, p);
57373916Sjhb			PROC_UNLOCK(p);
5741541Srgrimes			return;
5751541Srgrimes		}
5761541Srgrimes	}
57773916Sjhb	/*NOTREACHED*/
5781541Srgrimes}
5791541Srgrimes
5801541Srgrimes/*
5811541Srgrimes * Check that a proposed value to load into the .it_value or
5821541Srgrimes * .it_interval part of an interval timer is acceptable, and
5831541Srgrimes * fix it to have at least minimal value (i.e. if it is less
5841541Srgrimes * than the resolution of the clock, round it up.)
5851541Srgrimes */
5861549Srgrimesint
587102074Sphkitimerfix(struct timeval *tv)
5881541Srgrimes{
5891541Srgrimes
5901541Srgrimes	if (tv->tv_sec < 0 || tv->tv_sec > 100000000 ||
5911541Srgrimes	    tv->tv_usec < 0 || tv->tv_usec >= 1000000)
5921541Srgrimes		return (EINVAL);
5931541Srgrimes	if (tv->tv_sec == 0 && tv->tv_usec != 0 && tv->tv_usec < tick)
5941541Srgrimes		tv->tv_usec = tick;
5951541Srgrimes	return (0);
5961541Srgrimes}
5971541Srgrimes
5981541Srgrimes/*
5991541Srgrimes * Decrement an interval timer by a specified number
6001541Srgrimes * of microseconds, which must be less than a second,
6011541Srgrimes * i.e. < 1000000.  If the timer expires, then reload
6021541Srgrimes * it.  In this case, carry over (usec - old value) to
6031541Srgrimes * reduce the value reloaded into the timer so that
6041541Srgrimes * the timer does not drift.  This routine assumes
6051541Srgrimes * that it is called in a context where the timers
6061541Srgrimes * on which it is operating cannot change in value.
6071541Srgrimes */
6081549Srgrimesint
609102074Sphkitimerdecr(struct itimerval *itp, int usec)
6101541Srgrimes{
6111541Srgrimes
6121541Srgrimes	if (itp->it_value.tv_usec < usec) {
6131541Srgrimes		if (itp->it_value.tv_sec == 0) {
6141541Srgrimes			/* expired, and already in next interval */
6151541Srgrimes			usec -= itp->it_value.tv_usec;
6161541Srgrimes			goto expire;
6171541Srgrimes		}
6181541Srgrimes		itp->it_value.tv_usec += 1000000;
6191541Srgrimes		itp->it_value.tv_sec--;
6201541Srgrimes	}
6211541Srgrimes	itp->it_value.tv_usec -= usec;
6221541Srgrimes	usec = 0;
62335058Sphk	if (timevalisset(&itp->it_value))
6241541Srgrimes		return (1);
6251541Srgrimes	/* expired, exactly at end of interval */
6261541Srgrimesexpire:
62735058Sphk	if (timevalisset(&itp->it_interval)) {
6281541Srgrimes		itp->it_value = itp->it_interval;
6291541Srgrimes		itp->it_value.tv_usec -= usec;
6301541Srgrimes		if (itp->it_value.tv_usec < 0) {
6311541Srgrimes			itp->it_value.tv_usec += 1000000;
6321541Srgrimes			itp->it_value.tv_sec--;
6331541Srgrimes		}
6341541Srgrimes	} else
6351541Srgrimes		itp->it_value.tv_usec = 0;		/* sec is already 0 */
6361541Srgrimes	return (0);
6371541Srgrimes}
6381541Srgrimes
6391541Srgrimes/*
6401541Srgrimes * Add and subtract routines for timevals.
6411541Srgrimes * N.B.: subtract routine doesn't deal with
6421541Srgrimes * results which are before the beginning,
6431541Srgrimes * it just gets very confused in this case.
6441541Srgrimes * Caveat emptor.
6451541Srgrimes */
6461549Srgrimesvoid
647121523Salfredtimevaladd(struct timeval *t1, const struct timeval *t2)
6481541Srgrimes{
6491541Srgrimes
6501541Srgrimes	t1->tv_sec += t2->tv_sec;
6511541Srgrimes	t1->tv_usec += t2->tv_usec;
6521541Srgrimes	timevalfix(t1);
6531541Srgrimes}
6541541Srgrimes
6551549Srgrimesvoid
656121523Salfredtimevalsub(struct timeval *t1, const struct timeval *t2)
6571541Srgrimes{
6581541Srgrimes
6591541Srgrimes	t1->tv_sec -= t2->tv_sec;
6601541Srgrimes	t1->tv_usec -= t2->tv_usec;
6611541Srgrimes	timevalfix(t1);
6621541Srgrimes}
6631541Srgrimes
66412819Sphkstatic void
665102074Sphktimevalfix(struct timeval *t1)
6661541Srgrimes{
6671541Srgrimes
6681541Srgrimes	if (t1->tv_usec < 0) {
6691541Srgrimes		t1->tv_sec--;
6701541Srgrimes		t1->tv_usec += 1000000;
6711541Srgrimes	}
6721541Srgrimes	if (t1->tv_usec >= 1000000) {
6731541Srgrimes		t1->tv_sec++;
6741541Srgrimes		t1->tv_usec -= 1000000;
6751541Srgrimes	}
6761541Srgrimes}
677108142Ssam
678108142Ssam/*
679108511Ssam * ratecheck(): simple time-based rate-limit checking.
680108142Ssam */
681108142Ssamint
682108142Ssamratecheck(struct timeval *lasttime, const struct timeval *mininterval)
683108142Ssam{
684108142Ssam	struct timeval tv, delta;
685108142Ssam	int rv = 0;
686108142Ssam
687108511Ssam	getmicrouptime(&tv);		/* NB: 10ms precision */
688108511Ssam	delta = tv;
689108511Ssam	timevalsub(&delta, lasttime);
690108142Ssam
691108142Ssam	/*
692108142Ssam	 * check for 0,0 is so that the message will be seen at least once,
693108142Ssam	 * even if interval is huge.
694108142Ssam	 */
695108142Ssam	if (timevalcmp(&delta, mininterval, >=) ||
696108142Ssam	    (lasttime->tv_sec == 0 && lasttime->tv_usec == 0)) {
697108142Ssam		*lasttime = tv;
698108142Ssam		rv = 1;
699108142Ssam	}
700108142Ssam
701108142Ssam	return (rv);
702108142Ssam}
703108142Ssam
704108142Ssam/*
705108142Ssam * ppsratecheck(): packets (or events) per second limitation.
706108511Ssam *
707108511Ssam * Return 0 if the limit is to be enforced (e.g. the caller
708108511Ssam * should drop a packet because of the rate limitation).
709108511Ssam *
710111558Ssam * maxpps of 0 always causes zero to be returned.  maxpps of -1
711111558Ssam * always causes 1 to be returned; this effectively defeats rate
712111558Ssam * limiting.
713111558Ssam *
714108511Ssam * Note that we maintain the struct timeval for compatibility
715108511Ssam * with other bsd systems.  We reuse the storage and just monitor
716108511Ssam * clock ticks for minimal overhead.
717108142Ssam */
718108142Ssamint
719108142Ssamppsratecheck(struct timeval *lasttime, int *curpps, int maxpps)
720108142Ssam{
721108511Ssam	int now;
722108142Ssam
723108142Ssam	/*
724108511Ssam	 * Reset the last time and counter if this is the first call
725108511Ssam	 * or more than a second has passed since the last update of
726108511Ssam	 * lasttime.
727108142Ssam	 */
728108511Ssam	now = ticks;
729108511Ssam	if (lasttime->tv_sec == 0 || (u_int)(now - lasttime->tv_sec) >= hz) {
730108511Ssam		lasttime->tv_sec = now;
731108511Ssam		*curpps = 1;
732111558Ssam		return (maxpps != 0);
733108511Ssam	} else {
734108511Ssam		(*curpps)++;		/* NB: ignore potential overflow */
735108511Ssam		return (maxpps < 0 || *curpps < maxpps);
736108511Ssam	}
737108142Ssam}
738