123377Smckusick /*
263176Sbostic * Copyright (c) 1982, 1986, 1989, 1993
363176Sbostic * The Regents of the University of California. All rights reserved.
423377Smckusick *
544441Sbostic * %sccs.include.redist.c%
637583Smckusick *
7*69709Smckusick * @(#)kern_time.c 8.4 (Berkeley) 05/26/95
823377Smckusick */
97424Sroot
1056517Sbostic #include <sys/param.h>
1156517Sbostic #include <sys/resourcevar.h>
1256517Sbostic #include <sys/kernel.h>
1356517Sbostic #include <sys/systm.h>
1456517Sbostic #include <sys/proc.h>
1556517Sbostic #include <sys/vnode.h>
167424Sroot
1768304Scgd #include <sys/mount.h>
1868304Scgd #include <sys/syscallargs.h>
1968304Scgd
2056517Sbostic #include <machine/cpu.h>
2129946Skarels
228103Sroot /*
238103Sroot * Time of day and interval timer support.
248146Sroot *
258146Sroot * These routines provide the kernel entry points to get and set
268146Sroot * the time-of-day and per-process interval timers. Subroutines
278146Sroot * here provide support for adding and subtracting timeval structures
288146Sroot * and decrementing interval timers, optionally reloading the interval
298146Sroot * timers when they expire.
308103Sroot */
318103Sroot
3243392Skarels /* ARGSUSED */
3368304Scgd int
gettimeofday(p,uap,retval)3443392Skarels gettimeofday(p, uap, retval)
3543392Skarels struct proc *p;
3668304Scgd register struct gettimeofday_args /* {
3768304Scgd syscallarg(struct timeval *) tp;
3868304Scgd syscallarg(struct timezone *) tzp;
3968304Scgd } */ *uap;
4068304Scgd register_t *retval;
4143392Skarels {
428034Sroot struct timeval atv;
4343392Skarels int error = 0;
447500Sroot
4568304Scgd if (SCARG(uap, tp)) {
4630666Sbostic microtime(&atv);
4768304Scgd if (error = copyout((caddr_t)&atv, (caddr_t)SCARG(uap, tp),
4843392Skarels sizeof (atv)))
4944405Skarels return (error);
5030666Sbostic }
5168304Scgd if (SCARG(uap, tzp))
5268304Scgd error = copyout((caddr_t)&tz, (caddr_t)SCARG(uap, tzp),
5343392Skarels sizeof (tz));
5444405Skarels return (error);
557500Sroot }
567500Sroot
5745120Sbostic /* ARGSUSED */
5868304Scgd int
settimeofday(p,uap,retval)5943392Skarels settimeofday(p, uap, retval)
6043392Skarels struct proc *p;
6168304Scgd struct settimeofday_args /* {
6268304Scgd syscallarg(struct timeval *) tv;
6368304Scgd syscallarg(struct timezone *) tzp;
6468304Scgd } */ *uap;
6568304Scgd register_t *retval;
6643392Skarels {
6754784Storek struct timeval atv, delta;
688034Sroot struct timezone atz;
6943392Skarels int error, s;
707500Sroot
7147540Skarels if (error = suser(p->p_ucred, &p->p_acflag))
7244405Skarels return (error);
7354784Storek /* Verify all parameters before changing time. */
7468304Scgd if (SCARG(uap, tv) && (error = copyin((caddr_t)SCARG(uap, tv),
7568304Scgd (caddr_t)&atv, sizeof(atv))))
7654784Storek return (error);
7768304Scgd if (SCARG(uap, tzp) && (error = copyin((caddr_t)SCARG(uap, tzp),
7868304Scgd (caddr_t)&atz, sizeof(atz))))
7954784Storek return (error);
8068304Scgd if (SCARG(uap, tv)) {
81*69709Smckusick /*
82*69709Smckusick * If the system is secure, we do not allow the time to be
83*69709Smckusick * set to an earlier value (it may be slowed using adjtime,
84*69709Smckusick * but not set back). This feature prevent interlopers from
85*69709Smckusick * setting arbitrary time stamps on files.
86*69709Smckusick */
87*69709Smckusick if (securelevel > 0 && timercmp(&atv, &time, <))
88*69709Smckusick return (EPERM);
8937583Smckusick /* WHAT DO WE DO ABOUT PENDING REAL-TIME TIMEOUTS??? */
9054784Storek s = splclock();
9154784Storek /* nb. delta.tv_usec may be < 0, but this is OK here */
9254784Storek delta.tv_sec = atv.tv_sec - time.tv_sec;
9354784Storek delta.tv_usec = atv.tv_usec - time.tv_usec;
9454784Storek time = atv;
9554784Storek (void) splsoftclock();
9654784Storek timevaladd(&boottime, &delta);
9754784Storek timevalfix(&boottime);
9854784Storek timevaladd(&runtime, &delta);
9954784Storek timevalfix(&runtime);
10067639Smckusick # ifdef NFS
10167639Smckusick lease_updatetime(delta.tv_sec);
10267639Smckusick # endif
10354784Storek splx(s);
10437583Smckusick resettodr();
10530666Sbostic }
10668304Scgd if (SCARG(uap, tzp))
10737591Smckusick tz = atz;
10854784Storek return (0);
1097500Sroot }
1107500Sroot
11128829Skarels extern int tickadj; /* "standard" clock skew, us./tick */
11228829Skarels int tickdelta; /* current clock skew, us. per tick */
11328829Skarels long timedelta; /* unapplied time correction, us. */
11428829Skarels long bigadj = 1000000; /* use 10x skew above bigadj us. */
11517356Skarels
11643392Skarels /* ARGSUSED */
11768304Scgd int
adjtime(p,uap,retval)11843392Skarels adjtime(p, uap, retval)
11943392Skarels struct proc *p;
12068304Scgd register struct adjtime_args /* {
12168304Scgd syscallarg(struct timeval *) delta;
12268304Scgd syscallarg(struct timeval *) olddelta;
12368304Scgd } */ *uap;
12468304Scgd register_t *retval;
12543392Skarels {
12655293Storek struct timeval atv;
12755293Storek register long ndelta, ntickdelta, odelta;
12843392Skarels int s, error;
12917356Skarels
13047540Skarels if (error = suser(p->p_ucred, &p->p_acflag))
13144405Skarels return (error);
13268304Scgd if (error = copyin((caddr_t)SCARG(uap, delta), (caddr_t)&atv,
13368304Scgd sizeof(struct timeval)))
13444405Skarels return (error);
13555293Storek
13655293Storek /*
13755293Storek * Compute the total correction and the rate at which to apply it.
13855293Storek * Round the adjustment down to a whole multiple of the per-tick
13955293Storek * delta, so that after some number of incremental changes in
14055293Storek * hardclock(), tickdelta will become zero, lest the correction
14155293Storek * overshoot and start taking us away from the desired final time.
14255293Storek */
14328829Skarels ndelta = atv.tv_sec * 1000000 + atv.tv_usec;
14455293Storek if (ndelta > bigadj)
14555293Storek ntickdelta = 10 * tickadj;
14655293Storek else
14755293Storek ntickdelta = tickadj;
14855293Storek if (ndelta % ntickdelta)
14955293Storek ndelta = ndelta / ntickdelta * ntickdelta;
15028829Skarels
15155293Storek /*
15255293Storek * To make hardclock()'s job easier, make the per-tick delta negative
15355293Storek * if we want time to run slower; then hardclock can simply compute
15455293Storek * tick + tickdelta, and subtract tickdelta from timedelta.
15555293Storek */
15655293Storek if (ndelta < 0)
15755293Storek ntickdelta = -ntickdelta;
15825170Skarels s = splclock();
15955293Storek odelta = timedelta;
16028829Skarels timedelta = ndelta;
16155293Storek tickdelta = ntickdelta;
16228829Skarels splx(s);
16328829Skarels
16468304Scgd if (SCARG(uap, olddelta)) {
16555293Storek atv.tv_sec = odelta / 1000000;
16655293Storek atv.tv_usec = odelta % 1000000;
16768304Scgd (void) copyout((caddr_t)&atv, (caddr_t)SCARG(uap, olddelta),
16855293Storek sizeof(struct timeval));
16955293Storek }
17044405Skarels return (0);
17117356Skarels }
17217356Skarels
1738146Sroot /*
1748146Sroot * Get value of an interval timer. The process virtual and
17547540Skarels * profiling virtual time timers are kept in the p_stats area, since
1768146Sroot * they can be swapped out. These are kept internally in the
1778146Sroot * way they are specified externally: in time until they expire.
1788146Sroot *
1798146Sroot * The real time interval timer is kept in the process table slot
1808146Sroot * for the process, and its value (it_value) is kept as an
1818146Sroot * absolute time rather than as a delta, so that it is easy to keep
1828146Sroot * periodic real-time signals from drifting.
1838146Sroot *
1848146Sroot * Virtual time timers are processed in the hardclock() routine of
1858146Sroot * kern_clock.c. The real time timer is processed by a timeout
1868146Sroot * routine, called from the softclock() routine. Since a callout
1878146Sroot * may be delayed in real time due to interrupt processing in the system,
1888146Sroot * it is possible for the real time timeout routine (realitexpire, given below),
1898146Sroot * to be delayed in real time past when it is supposed to occur. It
1908146Sroot * does not suffice, therefore, to reload the real timer .it_value from the
1918146Sroot * real time timers .it_interval. Rather, we compute the next time in
1928146Sroot * absolute time the timer should go off.
1938146Sroot */
19443392Skarels /* ARGSUSED */
19568304Scgd int
getitimer(p,uap,retval)19643392Skarels getitimer(p, uap, retval)
19743392Skarels struct proc *p;
19868304Scgd register struct getitimer_args /* {
19968304Scgd syscallarg(u_int) which;
20068304Scgd syscallarg(struct itimerval *) itv;
20168304Scgd } */ *uap;
20268304Scgd register_t *retval;
20343392Skarels {
2048114Sroot struct itimerval aitv;
2058034Sroot int s;
2067424Sroot
20768304Scgd if (SCARG(uap, which) > ITIMER_PROF)
20844405Skarels return (EINVAL);
20925897Skarels s = splclock();
21068304Scgd if (SCARG(uap, which) == ITIMER_REAL) {
2118146Sroot /*
21268304Scgd * Convert from absolute to relative time in .it_value
2138146Sroot * part of real time timer. If time for real time timer
2148146Sroot * has passed return 0, else return difference between
2158146Sroot * current time and time for the timer to go off.
2168146Sroot */
21743392Skarels aitv = p->p_realtimer;
2188114Sroot if (timerisset(&aitv.it_value))
2198114Sroot if (timercmp(&aitv.it_value, &time, <))
2208114Sroot timerclear(&aitv.it_value);
2218114Sroot else
22254784Storek timevalsub(&aitv.it_value,
22354784Storek (struct timeval *)&time);
2248114Sroot } else
22568304Scgd aitv = p->p_stats->p_timer[SCARG(uap, which)];
2268114Sroot splx(s);
22768304Scgd return (copyout((caddr_t)&aitv, (caddr_t)SCARG(uap, itv),
22843392Skarels sizeof (struct itimerval)));
2297424Sroot }
2307424Sroot
23143392Skarels /* ARGSUSED */
23268304Scgd int
setitimer(p,uap,retval)23343392Skarels setitimer(p, uap, retval)
23443392Skarels struct proc *p;
23568304Scgd register struct setitimer_args /* {
23668304Scgd syscallarg(u_int) which;
23768304Scgd syscallarg(struct itimerval *) itv;
23868304Scgd syscallarg(struct itimerval *) oitv;
23968304Scgd } */ *uap;
24068304Scgd register_t *retval;
24143392Skarels {
24237591Smckusick struct itimerval aitv;
24337591Smckusick register struct itimerval *itvp;
24443392Skarels int s, error;
2457424Sroot
24668304Scgd if (SCARG(uap, which) > ITIMER_PROF)
24744405Skarels return (EINVAL);
24868304Scgd itvp = SCARG(uap, itv);
24943392Skarels if (itvp && (error = copyin((caddr_t)itvp, (caddr_t)&aitv,
25037591Smckusick sizeof(struct itimerval))))
25144405Skarels return (error);
25268304Scgd if ((SCARG(uap, itv) = SCARG(uap, oitv)) &&
25368304Scgd (error = getitimer(p, uap, retval)))
25444405Skarels return (error);
25537591Smckusick if (itvp == 0)
25643392Skarels return (0);
25743392Skarels if (itimerfix(&aitv.it_value) || itimerfix(&aitv.it_interval))
25844405Skarels return (EINVAL);
25925897Skarels s = splclock();
26068304Scgd if (SCARG(uap, which) == ITIMER_REAL) {
2618625Sroot untimeout(realitexpire, (caddr_t)p);
2628114Sroot if (timerisset(&aitv.it_value)) {
26354784Storek timevaladd(&aitv.it_value, (struct timeval *)&time);
2648625Sroot timeout(realitexpire, (caddr_t)p, hzto(&aitv.it_value));
2658114Sroot }
2668114Sroot p->p_realtimer = aitv;
2678114Sroot } else
26868304Scgd p->p_stats->p_timer[SCARG(uap, which)] = aitv;
2698034Sroot splx(s);
27044405Skarels return (0);
2717424Sroot }
2727424Sroot
2738146Sroot /*
2748146Sroot * Real interval timer expired:
2758146Sroot * send process whose timer expired an alarm signal.
2768146Sroot * If time is not set up to reload, then just return.
2778146Sroot * Else compute next time timer should go off which is > current time.
2788146Sroot * This is where delay in processing this timeout causes multiple
2798146Sroot * SIGALRM calls to be compressed into one.
2808146Sroot */
28154784Storek void
realitexpire(arg)28254784Storek realitexpire(arg)
28354784Storek void *arg;
28454784Storek {
2858114Sroot register struct proc *p;
2868114Sroot int s;
2878114Sroot
28854784Storek p = (struct proc *)arg;
2898114Sroot psignal(p, SIGALRM);
2908114Sroot if (!timerisset(&p->p_realtimer.it_interval)) {
2918114Sroot timerclear(&p->p_realtimer.it_value);
2928114Sroot return;
2938114Sroot }
2948114Sroot for (;;) {
29525897Skarels s = splclock();
2968114Sroot timevaladd(&p->p_realtimer.it_value,
2978114Sroot &p->p_realtimer.it_interval);
2988114Sroot if (timercmp(&p->p_realtimer.it_value, &time, >)) {
2998625Sroot timeout(realitexpire, (caddr_t)p,
3008625Sroot hzto(&p->p_realtimer.it_value));
3018114Sroot splx(s);
3028114Sroot return;
3038114Sroot }
3048114Sroot splx(s);
3058114Sroot }
3068114Sroot }
3078114Sroot
3088146Sroot /*
3098146Sroot * Check that a proposed value to load into the .it_value or
3108146Sroot * .it_interval part of an interval timer is acceptable, and
3118146Sroot * fix it to have at least minimal value (i.e. if it is less
3128146Sroot * than the resolution of the clock, round it up.)
3138146Sroot */
31468304Scgd int
itimerfix(tv)3158103Sroot itimerfix(tv)
3168103Sroot struct timeval *tv;
3177424Sroot {
3188034Sroot
3198114Sroot if (tv->tv_sec < 0 || tv->tv_sec > 100000000 ||
3208114Sroot tv->tv_usec < 0 || tv->tv_usec >= 1000000)
3218103Sroot return (EINVAL);
32212970Ssam if (tv->tv_sec == 0 && tv->tv_usec != 0 && tv->tv_usec < tick)
3238103Sroot tv->tv_usec = tick;
3248103Sroot return (0);
3258034Sroot }
3268034Sroot
3278146Sroot /*
3288146Sroot * Decrement an interval timer by a specified number
3298146Sroot * of microseconds, which must be less than a second,
3308146Sroot * i.e. < 1000000. If the timer expires, then reload
3318146Sroot * it. In this case, carry over (usec - old value) to
33254784Storek * reduce the value reloaded into the timer so that
3338146Sroot * the timer does not drift. This routine assumes
3348146Sroot * that it is called in a context where the timers
3358146Sroot * on which it is operating cannot change in value.
3368146Sroot */
33768304Scgd int
itimerdecr(itp,usec)3388034Sroot itimerdecr(itp, usec)
3398034Sroot register struct itimerval *itp;
3408034Sroot int usec;
3418034Sroot {
3428034Sroot
3438103Sroot if (itp->it_value.tv_usec < usec) {
3448103Sroot if (itp->it_value.tv_sec == 0) {
3458146Sroot /* expired, and already in next interval */
3468103Sroot usec -= itp->it_value.tv_usec;
3478034Sroot goto expire;
3488103Sroot }
3498103Sroot itp->it_value.tv_usec += 1000000;
3508103Sroot itp->it_value.tv_sec--;
3518034Sroot }
3528103Sroot itp->it_value.tv_usec -= usec;
3538103Sroot usec = 0;
3548103Sroot if (timerisset(&itp->it_value))
3558034Sroot return (1);
3568146Sroot /* expired, exactly at end of interval */
3578034Sroot expire:
3588103Sroot if (timerisset(&itp->it_interval)) {
3598103Sroot itp->it_value = itp->it_interval;
3608103Sroot itp->it_value.tv_usec -= usec;
3618103Sroot if (itp->it_value.tv_usec < 0) {
3628103Sroot itp->it_value.tv_usec += 1000000;
3638103Sroot itp->it_value.tv_sec--;
3648103Sroot }
3658103Sroot } else
3668146Sroot itp->it_value.tv_usec = 0; /* sec is already 0 */
3678034Sroot return (0);
3688034Sroot }
3698034Sroot
3708146Sroot /*
3718146Sroot * Add and subtract routines for timevals.
3728146Sroot * N.B.: subtract routine doesn't deal with
3738146Sroot * results which are before the beginning,
3748146Sroot * it just gets very confused in this case.
3758146Sroot * Caveat emptor.
3768146Sroot */
3778146Sroot timevaladd(t1, t2)
3788146Sroot struct timeval *t1, *t2;
3798146Sroot {
3808146Sroot
3818146Sroot t1->tv_sec += t2->tv_sec;
3828146Sroot t1->tv_usec += t2->tv_usec;
3838146Sroot timevalfix(t1);
3848146Sroot }
3858146Sroot
3868146Sroot timevalsub(t1, t2)
3878146Sroot struct timeval *t1, *t2;
3888146Sroot {
3898146Sroot
3908146Sroot t1->tv_sec -= t2->tv_sec;
3918146Sroot t1->tv_usec -= t2->tv_usec;
3928146Sroot timevalfix(t1);
3938146Sroot }
3948146Sroot
3958146Sroot timevalfix(t1)
3968146Sroot struct timeval *t1;
3978146Sroot {
3988146Sroot
3998146Sroot if (t1->tv_usec < 0) {
4008146Sroot t1->tv_sec--;
4018146Sroot t1->tv_usec += 1000000;
4028146Sroot }
4038146Sroot if (t1->tv_usec >= 1000000) {
4048146Sroot t1->tv_sec++;
4058146Sroot t1->tv_usec -= 1000000;
4068146Sroot }
4078146Sroot }
408