kern_time.c revision 1541
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
341541Srgrimes */
351541Srgrimes
361541Srgrimes#include <sys/param.h>
371541Srgrimes#include <sys/resourcevar.h>
381541Srgrimes#include <sys/kernel.h>
391541Srgrimes#include <sys/systm.h>
401541Srgrimes#include <sys/proc.h>
411541Srgrimes#include <sys/vnode.h>
421541Srgrimes
431541Srgrimes#include <machine/cpu.h>
441541Srgrimes
451541Srgrimes/*
461541Srgrimes * Time of day and interval timer support.
471541Srgrimes *
481541Srgrimes * These routines provide the kernel entry points to get and set
491541Srgrimes * the time-of-day and per-process interval timers.  Subroutines
501541Srgrimes * here provide support for adding and subtracting timeval structures
511541Srgrimes * and decrementing interval timers, optionally reloading the interval
521541Srgrimes * timers when they expire.
531541Srgrimes */
541541Srgrimes
551541Srgrimesstruct gettimeofday_args {
561541Srgrimes	struct	timeval *tp;
571541Srgrimes	struct	timezone *tzp;
581541Srgrimes};
591541Srgrimes/* ARGSUSED */
601541Srgrimesgettimeofday(p, uap, retval)
611541Srgrimes	struct proc *p;
621541Srgrimes	register struct gettimeofday_args *uap;
631541Srgrimes	int *retval;
641541Srgrimes{
651541Srgrimes	struct timeval atv;
661541Srgrimes	int error = 0;
671541Srgrimes
681541Srgrimes	if (uap->tp) {
691541Srgrimes		microtime(&atv);
701541Srgrimes		if (error = copyout((caddr_t)&atv, (caddr_t)uap->tp,
711541Srgrimes		    sizeof (atv)))
721541Srgrimes			return (error);
731541Srgrimes	}
741541Srgrimes	if (uap->tzp)
751541Srgrimes		error = copyout((caddr_t)&tz, (caddr_t)uap->tzp,
761541Srgrimes		    sizeof (tz));
771541Srgrimes	return (error);
781541Srgrimes}
791541Srgrimes
801541Srgrimesstruct settimeofday_args {
811541Srgrimes	struct	timeval *tv;
821541Srgrimes	struct	timezone *tzp;
831541Srgrimes};
841541Srgrimes/* ARGSUSED */
851541Srgrimessettimeofday(p, uap, retval)
861541Srgrimes	struct proc *p;
871541Srgrimes	struct settimeofday_args *uap;
881541Srgrimes	int *retval;
891541Srgrimes{
901541Srgrimes	struct timeval atv, delta;
911541Srgrimes	struct timezone atz;
921541Srgrimes	int error, s;
931541Srgrimes
941541Srgrimes	if (error = suser(p->p_ucred, &p->p_acflag))
951541Srgrimes		return (error);
961541Srgrimes	/* Verify all parameters before changing time. */
971541Srgrimes	if (uap->tv &&
981541Srgrimes	    (error = copyin((caddr_t)uap->tv, (caddr_t)&atv, sizeof(atv))))
991541Srgrimes		return (error);
1001541Srgrimes	if (uap->tzp &&
1011541Srgrimes	    (error = copyin((caddr_t)uap->tzp, (caddr_t)&atz, sizeof(atz))))
1021541Srgrimes		return (error);
1031541Srgrimes	if (uap->tv) {
1041541Srgrimes		/* WHAT DO WE DO ABOUT PENDING REAL-TIME TIMEOUTS??? */
1051541Srgrimes		s = splclock();
1061541Srgrimes		/* nb. delta.tv_usec may be < 0, but this is OK here */
1071541Srgrimes		delta.tv_sec = atv.tv_sec - time.tv_sec;
1081541Srgrimes		delta.tv_usec = atv.tv_usec - time.tv_usec;
1091541Srgrimes		time = atv;
1101541Srgrimes		(void) splsoftclock();
1111541Srgrimes		timevaladd(&boottime, &delta);
1121541Srgrimes		timevalfix(&boottime);
1131541Srgrimes		timevaladd(&runtime, &delta);
1141541Srgrimes		timevalfix(&runtime);
1151541Srgrimes		LEASE_UPDATETIME(delta.tv_sec);
1161541Srgrimes		splx(s);
1171541Srgrimes		resettodr();
1181541Srgrimes	}
1191541Srgrimes	if (uap->tzp)
1201541Srgrimes		tz = atz;
1211541Srgrimes	return (0);
1221541Srgrimes}
1231541Srgrimes
1241541Srgrimesextern	int tickadj;			/* "standard" clock skew, us./tick */
1251541Srgrimesint	tickdelta;			/* current clock skew, us. per tick */
1261541Srgrimeslong	timedelta;			/* unapplied time correction, us. */
1271541Srgrimeslong	bigadj = 1000000;		/* use 10x skew above bigadj us. */
1281541Srgrimes
1291541Srgrimesstruct adjtime_args {
1301541Srgrimes	struct timeval *delta;
1311541Srgrimes	struct timeval *olddelta;
1321541Srgrimes};
1331541Srgrimes/* ARGSUSED */
1341541Srgrimesadjtime(p, uap, retval)
1351541Srgrimes	struct proc *p;
1361541Srgrimes	register struct adjtime_args *uap;
1371541Srgrimes	int *retval;
1381541Srgrimes{
1391541Srgrimes	struct timeval atv;
1401541Srgrimes	register long ndelta, ntickdelta, odelta;
1411541Srgrimes	int s, error;
1421541Srgrimes
1431541Srgrimes	if (error = suser(p->p_ucred, &p->p_acflag))
1441541Srgrimes		return (error);
1451541Srgrimes	if (error =
1461541Srgrimes	    copyin((caddr_t)uap->delta, (caddr_t)&atv, sizeof(struct timeval)))
1471541Srgrimes		return (error);
1481541Srgrimes
1491541Srgrimes	/*
1501541Srgrimes	 * Compute the total correction and the rate at which to apply it.
1511541Srgrimes	 * Round the adjustment down to a whole multiple of the per-tick
1521541Srgrimes	 * delta, so that after some number of incremental changes in
1531541Srgrimes	 * hardclock(), tickdelta will become zero, lest the correction
1541541Srgrimes	 * overshoot and start taking us away from the desired final time.
1551541Srgrimes	 */
1561541Srgrimes	ndelta = atv.tv_sec * 1000000 + atv.tv_usec;
1571541Srgrimes	if (ndelta > bigadj)
1581541Srgrimes		ntickdelta = 10 * tickadj;
1591541Srgrimes	else
1601541Srgrimes		ntickdelta = tickadj;
1611541Srgrimes	if (ndelta % ntickdelta)
1621541Srgrimes		ndelta = ndelta / ntickdelta * ntickdelta;
1631541Srgrimes
1641541Srgrimes	/*
1651541Srgrimes	 * To make hardclock()'s job easier, make the per-tick delta negative
1661541Srgrimes	 * if we want time to run slower; then hardclock can simply compute
1671541Srgrimes	 * tick + tickdelta, and subtract tickdelta from timedelta.
1681541Srgrimes	 */
1691541Srgrimes	if (ndelta < 0)
1701541Srgrimes		ntickdelta = -ntickdelta;
1711541Srgrimes	s = splclock();
1721541Srgrimes	odelta = timedelta;
1731541Srgrimes	timedelta = ndelta;
1741541Srgrimes	tickdelta = ntickdelta;
1751541Srgrimes	splx(s);
1761541Srgrimes
1771541Srgrimes	if (uap->olddelta) {
1781541Srgrimes		atv.tv_sec = odelta / 1000000;
1791541Srgrimes		atv.tv_usec = odelta % 1000000;
1801541Srgrimes		(void) copyout((caddr_t)&atv, (caddr_t)uap->olddelta,
1811541Srgrimes		    sizeof(struct timeval));
1821541Srgrimes	}
1831541Srgrimes	return (0);
1841541Srgrimes}
1851541Srgrimes
1861541Srgrimes/*
1871541Srgrimes * Get value of an interval timer.  The process virtual and
1881541Srgrimes * profiling virtual time timers are kept in the p_stats area, since
1891541Srgrimes * they can be swapped out.  These are kept internally in the
1901541Srgrimes * way they are specified externally: in time until they expire.
1911541Srgrimes *
1921541Srgrimes * The real time interval timer is kept in the process table slot
1931541Srgrimes * for the process, and its value (it_value) is kept as an
1941541Srgrimes * absolute time rather than as a delta, so that it is easy to keep
1951541Srgrimes * periodic real-time signals from drifting.
1961541Srgrimes *
1971541Srgrimes * Virtual time timers are processed in the hardclock() routine of
1981541Srgrimes * kern_clock.c.  The real time timer is processed by a timeout
1991541Srgrimes * routine, called from the softclock() routine.  Since a callout
2001541Srgrimes * may be delayed in real time due to interrupt processing in the system,
2011541Srgrimes * it is possible for the real time timeout routine (realitexpire, given below),
2021541Srgrimes * to be delayed in real time past when it is supposed to occur.  It
2031541Srgrimes * does not suffice, therefore, to reload the real timer .it_value from the
2041541Srgrimes * real time timers .it_interval.  Rather, we compute the next time in
2051541Srgrimes * absolute time the timer should go off.
2061541Srgrimes */
2071541Srgrimesstruct getitimer_args {
2081541Srgrimes	u_int	which;
2091541Srgrimes	struct	itimerval *itv;
2101541Srgrimes};
2111541Srgrimes/* ARGSUSED */
2121541Srgrimesgetitimer(p, uap, retval)
2131541Srgrimes	struct proc *p;
2141541Srgrimes	register struct getitimer_args *uap;
2151541Srgrimes	int *retval;
2161541Srgrimes{
2171541Srgrimes	struct itimerval aitv;
2181541Srgrimes	int s;
2191541Srgrimes
2201541Srgrimes	if (uap->which > ITIMER_PROF)
2211541Srgrimes		return (EINVAL);
2221541Srgrimes	s = splclock();
2231541Srgrimes	if (uap->which == ITIMER_REAL) {
2241541Srgrimes		/*
2251541Srgrimes		 * Convert from absoulte to relative time in .it_value
2261541Srgrimes		 * part of real time timer.  If time for real time timer
2271541Srgrimes		 * has passed return 0, else return difference between
2281541Srgrimes		 * current time and time for the timer to go off.
2291541Srgrimes		 */
2301541Srgrimes		aitv = p->p_realtimer;
2311541Srgrimes		if (timerisset(&aitv.it_value))
2321541Srgrimes			if (timercmp(&aitv.it_value, &time, <))
2331541Srgrimes				timerclear(&aitv.it_value);
2341541Srgrimes			else
2351541Srgrimes				timevalsub(&aitv.it_value,
2361541Srgrimes				    (struct timeval *)&time);
2371541Srgrimes	} else
2381541Srgrimes		aitv = p->p_stats->p_timer[uap->which];
2391541Srgrimes	splx(s);
2401541Srgrimes	return (copyout((caddr_t)&aitv, (caddr_t)uap->itv,
2411541Srgrimes	    sizeof (struct itimerval)));
2421541Srgrimes}
2431541Srgrimes
2441541Srgrimesstruct setitimer_args {
2451541Srgrimes	u_int	which;
2461541Srgrimes	struct	itimerval *itv, *oitv;
2471541Srgrimes};
2481541Srgrimes/* ARGSUSED */
2491541Srgrimessetitimer(p, uap, retval)
2501541Srgrimes	struct proc *p;
2511541Srgrimes	register struct setitimer_args *uap;
2521541Srgrimes	int *retval;
2531541Srgrimes{
2541541Srgrimes	struct itimerval aitv;
2551541Srgrimes	register struct itimerval *itvp;
2561541Srgrimes	int s, error;
2571541Srgrimes
2581541Srgrimes	if (uap->which > ITIMER_PROF)
2591541Srgrimes		return (EINVAL);
2601541Srgrimes	itvp = uap->itv;
2611541Srgrimes	if (itvp && (error = copyin((caddr_t)itvp, (caddr_t)&aitv,
2621541Srgrimes	    sizeof(struct itimerval))))
2631541Srgrimes		return (error);
2641541Srgrimes	if ((uap->itv = uap->oitv) && (error = getitimer(p, uap, retval)))
2651541Srgrimes		return (error);
2661541Srgrimes	if (itvp == 0)
2671541Srgrimes		return (0);
2681541Srgrimes	if (itimerfix(&aitv.it_value) || itimerfix(&aitv.it_interval))
2691541Srgrimes		return (EINVAL);
2701541Srgrimes	s = splclock();
2711541Srgrimes	if (uap->which == ITIMER_REAL) {
2721541Srgrimes		untimeout(realitexpire, (caddr_t)p);
2731541Srgrimes		if (timerisset(&aitv.it_value)) {
2741541Srgrimes			timevaladd(&aitv.it_value, (struct timeval *)&time);
2751541Srgrimes			timeout(realitexpire, (caddr_t)p, hzto(&aitv.it_value));
2761541Srgrimes		}
2771541Srgrimes		p->p_realtimer = aitv;
2781541Srgrimes	} else
2791541Srgrimes		p->p_stats->p_timer[uap->which] = aitv;
2801541Srgrimes	splx(s);
2811541Srgrimes	return (0);
2821541Srgrimes}
2831541Srgrimes
2841541Srgrimes/*
2851541Srgrimes * Real interval timer expired:
2861541Srgrimes * send process whose timer expired an alarm signal.
2871541Srgrimes * If time is not set up to reload, then just return.
2881541Srgrimes * Else compute next time timer should go off which is > current time.
2891541Srgrimes * This is where delay in processing this timeout causes multiple
2901541Srgrimes * SIGALRM calls to be compressed into one.
2911541Srgrimes */
2921541Srgrimesvoid
2931541Srgrimesrealitexpire(arg)
2941541Srgrimes	void *arg;
2951541Srgrimes{
2961541Srgrimes	register struct proc *p;
2971541Srgrimes	int s;
2981541Srgrimes
2991541Srgrimes	p = (struct proc *)arg;
3001541Srgrimes	psignal(p, SIGALRM);
3011541Srgrimes	if (!timerisset(&p->p_realtimer.it_interval)) {
3021541Srgrimes		timerclear(&p->p_realtimer.it_value);
3031541Srgrimes		return;
3041541Srgrimes	}
3051541Srgrimes	for (;;) {
3061541Srgrimes		s = splclock();
3071541Srgrimes		timevaladd(&p->p_realtimer.it_value,
3081541Srgrimes		    &p->p_realtimer.it_interval);
3091541Srgrimes		if (timercmp(&p->p_realtimer.it_value, &time, >)) {
3101541Srgrimes			timeout(realitexpire, (caddr_t)p,
3111541Srgrimes			    hzto(&p->p_realtimer.it_value));
3121541Srgrimes			splx(s);
3131541Srgrimes			return;
3141541Srgrimes		}
3151541Srgrimes		splx(s);
3161541Srgrimes	}
3171541Srgrimes}
3181541Srgrimes
3191541Srgrimes/*
3201541Srgrimes * Check that a proposed value to load into the .it_value or
3211541Srgrimes * .it_interval part of an interval timer is acceptable, and
3221541Srgrimes * fix it to have at least minimal value (i.e. if it is less
3231541Srgrimes * than the resolution of the clock, round it up.)
3241541Srgrimes */
3251541Srgrimesitimerfix(tv)
3261541Srgrimes	struct timeval *tv;
3271541Srgrimes{
3281541Srgrimes
3291541Srgrimes	if (tv->tv_sec < 0 || tv->tv_sec > 100000000 ||
3301541Srgrimes	    tv->tv_usec < 0 || tv->tv_usec >= 1000000)
3311541Srgrimes		return (EINVAL);
3321541Srgrimes	if (tv->tv_sec == 0 && tv->tv_usec != 0 && tv->tv_usec < tick)
3331541Srgrimes		tv->tv_usec = tick;
3341541Srgrimes	return (0);
3351541Srgrimes}
3361541Srgrimes
3371541Srgrimes/*
3381541Srgrimes * Decrement an interval timer by a specified number
3391541Srgrimes * of microseconds, which must be less than a second,
3401541Srgrimes * i.e. < 1000000.  If the timer expires, then reload
3411541Srgrimes * it.  In this case, carry over (usec - old value) to
3421541Srgrimes * reduce the value reloaded into the timer so that
3431541Srgrimes * the timer does not drift.  This routine assumes
3441541Srgrimes * that it is called in a context where the timers
3451541Srgrimes * on which it is operating cannot change in value.
3461541Srgrimes */
3471541Srgrimesitimerdecr(itp, usec)
3481541Srgrimes	register struct itimerval *itp;
3491541Srgrimes	int usec;
3501541Srgrimes{
3511541Srgrimes
3521541Srgrimes	if (itp->it_value.tv_usec < usec) {
3531541Srgrimes		if (itp->it_value.tv_sec == 0) {
3541541Srgrimes			/* expired, and already in next interval */
3551541Srgrimes			usec -= itp->it_value.tv_usec;
3561541Srgrimes			goto expire;
3571541Srgrimes		}
3581541Srgrimes		itp->it_value.tv_usec += 1000000;
3591541Srgrimes		itp->it_value.tv_sec--;
3601541Srgrimes	}
3611541Srgrimes	itp->it_value.tv_usec -= usec;
3621541Srgrimes	usec = 0;
3631541Srgrimes	if (timerisset(&itp->it_value))
3641541Srgrimes		return (1);
3651541Srgrimes	/* expired, exactly at end of interval */
3661541Srgrimesexpire:
3671541Srgrimes	if (timerisset(&itp->it_interval)) {
3681541Srgrimes		itp->it_value = itp->it_interval;
3691541Srgrimes		itp->it_value.tv_usec -= usec;
3701541Srgrimes		if (itp->it_value.tv_usec < 0) {
3711541Srgrimes			itp->it_value.tv_usec += 1000000;
3721541Srgrimes			itp->it_value.tv_sec--;
3731541Srgrimes		}
3741541Srgrimes	} else
3751541Srgrimes		itp->it_value.tv_usec = 0;		/* sec is already 0 */
3761541Srgrimes	return (0);
3771541Srgrimes}
3781541Srgrimes
3791541Srgrimes/*
3801541Srgrimes * Add and subtract routines for timevals.
3811541Srgrimes * N.B.: subtract routine doesn't deal with
3821541Srgrimes * results which are before the beginning,
3831541Srgrimes * it just gets very confused in this case.
3841541Srgrimes * Caveat emptor.
3851541Srgrimes */
3861541Srgrimestimevaladd(t1, t2)
3871541Srgrimes	struct timeval *t1, *t2;
3881541Srgrimes{
3891541Srgrimes
3901541Srgrimes	t1->tv_sec += t2->tv_sec;
3911541Srgrimes	t1->tv_usec += t2->tv_usec;
3921541Srgrimes	timevalfix(t1);
3931541Srgrimes}
3941541Srgrimes
3951541Srgrimestimevalsub(t1, t2)
3961541Srgrimes	struct timeval *t1, *t2;
3971541Srgrimes{
3981541Srgrimes
3991541Srgrimes	t1->tv_sec -= t2->tv_sec;
4001541Srgrimes	t1->tv_usec -= t2->tv_usec;
4011541Srgrimes	timevalfix(t1);
4021541Srgrimes}
4031541Srgrimes
4041541Srgrimestimevalfix(t1)
4051541Srgrimes	struct timeval *t1;
4061541Srgrimes{
4071541Srgrimes
4081541Srgrimes	if (t1->tv_usec < 0) {
4091541Srgrimes		t1->tv_sec--;
4101541Srgrimes		t1->tv_usec += 1000000;
4111541Srgrimes	}
4121541Srgrimes	if (t1->tv_usec >= 1000000) {
4131541Srgrimes		t1->tv_sec++;
4141541Srgrimes		t1->tv_usec -= 1000000;
4151541Srgrimes	}
4161541Srgrimes}
417