X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/4f23be1099f16b79ac27b991c7146924b0940f91..8429d0227448605965610a9e25ac573e07e17507:/usr/src/sys/kern/kern_time.c?ds=inline diff --git a/usr/src/sys/kern/kern_time.c b/usr/src/sys/kern/kern_time.c index 28607a7974..e61955b6b9 100644 --- a/usr/src/sys/kern/kern_time.c +++ b/usr/src/sys/kern/kern_time.c @@ -1,13 +1,17 @@ -/* kern_time.c 5.14 82/12/30 */ +/* + * Copyright (c) 1982, 1986, 1989 Regents of the University of California. + * All rights reserved. + * + * %sccs.include.redist.c% + * + * @(#)kern_time.c 7.15 (Berkeley) %G% + */ -#include "../machine/reg.h" +#include "param.h" +#include "resourcevar.h" +#include "kernel.h" +#include "proc.h" -#include "../h/param.h" -#include "../h/dir.h" /* XXX */ -#include "../h/user.h" -#include "../h/kernel.h" -#include "../h/inode.h" -#include "../h/proc.h" /* * Time of day and interval timer support. @@ -19,63 +23,109 @@ * timers when they expire. */ -gettimeofday() -{ - register struct a { +/* ARGSUSED */ +gettimeofday(p, uap, retval) + struct proc *p; + register struct args { struct timeval *tp; struct timezone *tzp; - } *uap = (struct a *)u.u_ap; + } *uap; + int *retval; +{ struct timeval atv; - int s; + int error = 0; - s = spl7(); atv = time; splx(s); - u.u_error = copyout((caddr_t)&atv, (caddr_t)uap->tp, sizeof (atv)); - if (u.u_error) - return; - if (uap->tzp == 0) - return; - /* SHOULD HAVE PER-PROCESS TIMEZONE */ - u.u_error = copyout((caddr_t)&tz, (caddr_t)uap->tzp, sizeof (tz)); + if (uap->tp) { + microtime(&atv); + if (error = copyout((caddr_t)&atv, (caddr_t)uap->tp, + sizeof (atv))) + return (error); + } + if (uap->tzp) + error = copyout((caddr_t)&tz, (caddr_t)uap->tzp, + sizeof (tz)); + return (error); } -settimeofday() -{ - register struct a { +/* ARGSUSED */ +settimeofday(p, uap, retval) + struct proc *p; + struct args { struct timeval *tv; struct timezone *tzp; - } *uap = (struct a *)u.u_ap; + } *uap; + int *retval; +{ struct timeval atv; struct timezone atz; - - u.u_error = copyin((caddr_t)uap->tv, (caddr_t)&atv, - sizeof (struct timeval)); - if (u.u_error) - return; - setthetime(&atv); - if (uap->tzp && suser()) { - u.u_error = copyin((caddr_t)uap->tzp, (caddr_t)&atz, - sizeof (atz)); - if (u.u_error) - return; + int error, s; + + if (error = suser(p->p_ucred, &p->p_acflag)) + return (error); + if (uap->tv) { + if (error = copyin((caddr_t)uap->tv, (caddr_t)&atv, + sizeof (struct timeval))) + return (error); + /* WHAT DO WE DO ABOUT PENDING REAL-TIME TIMEOUTS??? */ + boottime.tv_sec += atv.tv_sec - time.tv_sec; + s = splhigh(); time = atv; splx(s); + resettodr(); } + if (uap->tzp && (error = copyin((caddr_t)uap->tzp, (caddr_t)&atz, + sizeof (atz))) == 0) + tz = atz; + return (error); } -setthetime(tv) - struct timeval *tv; +extern int tickadj; /* "standard" clock skew, us./tick */ +int tickdelta; /* current clock skew, us. per tick */ +long timedelta; /* unapplied time correction, us. */ +long bigadj = 1000000; /* use 10x skew above bigadj us. */ + +/* ARGSUSED */ +adjtime(p, uap, retval) + struct proc *p; + register struct args { + struct timeval *delta; + struct timeval *olddelta; + } *uap; + int *retval; { - int s; + struct timeval atv, oatv; + register long ndelta; + int s, error; + + if (error = suser(p->p_ucred, &p->p_acflag)) + return (error); + if (error = + copyin((caddr_t)uap->delta, (caddr_t)&atv, sizeof (struct timeval))) + return (error); + ndelta = atv.tv_sec * 1000000 + atv.tv_usec; + if (timedelta == 0) + if (ndelta > bigadj) + tickdelta = 10 * tickadj; + else + tickdelta = tickadj; + if (ndelta % tickdelta) + ndelta = ndelta / tickadj * tickadj; + + s = splclock(); + if (uap->olddelta) { + oatv.tv_sec = timedelta / 1000000; + oatv.tv_usec = timedelta % 1000000; + } + timedelta = ndelta; + splx(s); - if (!suser()) - return; -/* WHAT DO WE DO ABOUT PENDING REAL-TIME TIMEOUTS??? */ - boottime.tv_sec += tv->tv_sec - time.tv_sec; - s = spl7(); time = *tv; splx(s); - resettodr(); + if (uap->olddelta) + (void) copyout((caddr_t)&oatv, (caddr_t)uap->olddelta, + sizeof (struct timeval)); + return (0); } /* * Get value of an interval timer. The process virtual and - * profiling virtual time timers are kept in the u. area, since + * profiling virtual time timers are kept in the p_stats area, since * they can be swapped out. These are kept internally in the * way they are specified externally: in time until they expire. * @@ -94,20 +144,21 @@ setthetime(tv) * real time timers .it_interval. Rather, we compute the next time in * absolute time the timer should go off. */ -getitimer() -{ - register struct a { +/* ARGSUSED */ +getitimer(p, uap, retval) + struct proc *p; + register struct args { u_int which; struct itimerval *itv; - } *uap = (struct a *)u.u_ap; + } *uap; + int *retval; +{ struct itimerval aitv; int s; - if (uap->which > 2) { - u.u_error = EINVAL; - return; - } - s = spl7(); + if (uap->which > ITIMER_PROF) + return (EINVAL); + s = splclock(); if (uap->which == ITIMER_REAL) { /* * Convert from absoulte to relative time in .it_value @@ -115,47 +166,45 @@ getitimer() * has passed return 0, else return difference between * current time and time for the timer to go off. */ - aitv = u.u_procp->p_realtimer; + aitv = p->p_realtimer; if (timerisset(&aitv.it_value)) if (timercmp(&aitv.it_value, &time, <)) timerclear(&aitv.it_value); else timevalsub(&aitv.it_value, &time); } else - aitv = u.u_timer[uap->which]; - splx(s); - u.u_error = copyout((caddr_t)&aitv, (caddr_t)uap->itv, - sizeof (struct itimerval)); + aitv = p->p_stats->p_timer[uap->which]; splx(s); + return (copyout((caddr_t)&aitv, (caddr_t)uap->itv, + sizeof (struct itimerval))); } -setitimer() -{ - register struct a { +/* ARGSUSED */ +setitimer(p, uap, retval) + struct proc *p; + register struct args { u_int which; struct itimerval *itv, *oitv; - } *uap = (struct a *)u.u_ap; + } *uap; + int *retval; +{ struct itimerval aitv; - int s; - register struct proc *p = u.u_procp; + register struct itimerval *itvp; + int s, error; - if (uap->which > 2) { - u.u_error = EINVAL; - return; - } - u.u_error = copyin((caddr_t)uap->itv, (caddr_t)&aitv, - sizeof (struct itimerval)); - if (u.u_error) - return; - if (uap->oitv) { - uap->itv = uap->oitv; - getitimer(); - } - if (itimerfix(&aitv.it_value) || itimerfix(&aitv.it_interval)) { - u.u_error = EINVAL; - return; - } - s = spl7(); + if (uap->which > ITIMER_PROF) + return (EINVAL); + itvp = uap->itv; + if (itvp && (error = copyin((caddr_t)itvp, (caddr_t)&aitv, + sizeof(struct itimerval)))) + return (error); + if ((uap->itv = uap->oitv) && (error = getitimer(p, uap, retval))) + return (error); + if (itvp == 0) + return (0); + if (itimerfix(&aitv.it_value) || itimerfix(&aitv.it_interval)) + return (EINVAL); + s = splclock(); if (uap->which == ITIMER_REAL) { untimeout(realitexpire, (caddr_t)p); if (timerisset(&aitv.it_value)) { @@ -164,8 +213,9 @@ setitimer() } p->p_realtimer = aitv; } else - u.u_timer[uap->which] = aitv; + p->p_stats->p_timer[uap->which] = aitv; splx(s); + return (0); } /* @@ -187,7 +237,7 @@ realitexpire(p) return; } for (;;) { - s = spl7(); + s = splclock(); timevaladd(&p->p_realtimer.it_value, &p->p_realtimer.it_interval); if (timercmp(&p->p_realtimer.it_value, &time, >)) { @@ -213,7 +263,7 @@ itimerfix(tv) if (tv->tv_sec < 0 || tv->tv_sec > 100000000 || tv->tv_usec < 0 || tv->tv_usec >= 1000000) return (EINVAL); - if (tv->tv_sec == 0 && tv->tv_usec < tick) + if (tv->tv_sec == 0 && tv->tv_usec != 0 && tv->tv_usec < tick) tv->tv_usec = tick; return (0); } @@ -298,73 +348,3 @@ timevalfix(t1) t1->tv_usec -= 1000000; } } - -#ifndef NOCOMPAT -otime() -{ - - u.u_r.r_time = time.tv_sec; -} - -ostime() -{ - register struct a { - int time; - } *uap = (struct a *)u.u_ap; - struct timeval tv; - - tv.tv_sec = uap->time; - tv.tv_usec = 0; - setthetime(&tv); -} - -/* from old timeb.h */ -struct timeb { - time_t time; - u_short millitm; - short timezone; - short dstflag; -}; - -oftime() -{ - register struct a { - struct timeb *tp; - } *uap; - struct timeb tb; - - uap = (struct a *)u.u_ap; - (void) spl7(); - tb.time = time.tv_sec; - tb.millitm = time.tv_usec / 1000; - (void) spl0(); - tb.timezone = tz.tz_minuteswest; - tb.dstflag = tz.tz_dsttime; - u.u_error = copyout((caddr_t)&tb, (caddr_t)uap->tp, sizeof (tb)); -} - -oalarm() -{ - register struct a { - int deltat; - } *uap = (struct a *)u.u_ap; - register struct proc *p = u.u_procp; - int s = spl7(); - - untimeout(realitexpire, (caddr_t)p); - timerclear(&p->p_realtimer.it_interval); - u.u_r.r_val1 = 0; - if (timerisset(&p->p_realtimer.it_value) && - timercmp(&p->p_realtimer.it_value, &time, >)) - u.u_r.r_val1 = p->p_realtimer.it_value.tv_sec - time.tv_sec; - if (uap->deltat == 0) { - timerclear(&p->p_realtimer.it_value); - splx(s); - return; - } - p->p_realtimer.it_value = time; - p->p_realtimer.it_value.tv_sec += uap->deltat; - timeout(realitexpire, (caddr_t)p, hzto(&p->p_realtimer.it_value)); - splx(s); -} -#endif