X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/aa2615055535bde302dfd736eb4f32660e7e162a..39f14191e3f9fce7f823ec8e2c50b62274cfb48b:/usr/src/sys/kern/kern_time.c diff --git a/usr/src/sys/kern/kern_time.c b/usr/src/sys/kern/kern_time.c index 8419fe00e1..7f2dfbc478 100644 --- a/usr/src/sys/kern/kern_time.c +++ b/usr/src/sys/kern/kern_time.c @@ -1,12 +1,19 @@ -/* kern_time.c 5.7 82/09/11 */ +/* + * Copyright (c) 1982, 1986 Regents of the University of California. + * All rights reserved. The Berkeley software License Agreement + * specifies the terms and conditions for redistribution. + * + * @(#)kern_time.c 7.2 (Berkeley) %G% + */ + +#include "../machine/reg.h" -#include "../h/param.h" -#include "../h/dir.h" /* XXX */ -#include "../h/user.h" -#include "../h/kernel.h" -#include "../h/reg.h" -#include "../h/inode.h" -#include "../h/proc.h" +#include "param.h" +#include "dir.h" /* XXX */ +#include "user.h" +#include "kernel.h" +#include "inode.h" +#include "proc.h" /* * Time of day and interval timer support. @@ -25,20 +32,15 @@ gettimeofday() struct timezone *tzp; } *uap = (struct a *)u.u_ap; struct timeval atv; - int s; - s = spl7(); atv = time; splx(s); - if (copyout((caddr_t)&atv, (caddr_t)uap->tp, sizeof (atv))) { - u.u_error = EFAULT; + microtime(&atv); + 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 */ - if (copyout((caddr_t)&tz, uap->tzp, sizeof (tz))) { - u.u_error = EFAULT; - return; - } + u.u_error = copyout((caddr_t)&tz, (caddr_t)uap->tzp, sizeof (tz)); } settimeofday() @@ -50,31 +52,73 @@ settimeofday() struct timeval atv; struct timezone atz; - if (copyin((caddr_t)uap->tv, (caddr_t)&atv, sizeof (struct timeval))) { - u.u_error = EFAULT; + 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()) { - if (copyin((caddr_t)uap->tzp, (caddr_t)&atz, sizeof (atz))) { - u.u_error = EFAULT; - return; - } + u.u_error = copyin((caddr_t)uap->tzp, (caddr_t)&atz, + sizeof (atz)); + if (u.u_error == 0) + tz = atz; } } setthetime(tv) struct timeval *tv; { - register int delta; int 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); - clockset(); + s = splhigh(); time = *tv; splx(s); + resettodr(); +} + +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. */ + +adjtime() +{ + register struct a { + struct timeval *delta; + struct timeval *olddelta; + } *uap = (struct a *)u.u_ap; + struct timeval atv, oatv; + register long ndelta; + int s; + + if (!suser()) + return; + u.u_error = copyin((caddr_t)uap->delta, (caddr_t)&atv, + sizeof (struct timeval)); + if (u.u_error) + return; + 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 (uap->olddelta) + (void) copyout((caddr_t)&oatv, (caddr_t)uap->olddelta, + sizeof (struct timeval)); } /* @@ -111,7 +155,7 @@ getitimer() u.u_error = EINVAL; return; } - s = spl7(); + s = splclock(); if (uap->which == ITIMER_REAL) { /* * Convert from absoulte to relative time in .it_value @@ -128,9 +172,8 @@ getitimer() } else aitv = u.u_timer[uap->which]; splx(s); - if (copyout((caddr_t)&aitv, uap->itv, sizeof (struct itimerval))) - u.u_error = EFAULT; - splx(s); + u.u_error = copyout((caddr_t)&aitv, (caddr_t)uap->itv, + sizeof (struct itimerval)); } setitimer() @@ -139,7 +182,7 @@ setitimer() u_int which; struct itimerval *itv, *oitv; } *uap = (struct a *)u.u_ap; - struct itimerval aitv; + struct itimerval aitv, *aitvp; int s; register struct proc *p = u.u_procp; @@ -147,25 +190,27 @@ setitimer() u.u_error = EINVAL; return; } - if (copyin((caddr_t)uap->itv, (caddr_t)&aitv, - sizeof (struct itimerval))) { - u.u_error = EFAULT; - return; - } + aitvp = uap->itv; if (uap->oitv) { uap->itv = uap->oitv; getitimer(); } + if (aitvp == 0) + return; + u.u_error = copyin((caddr_t)aitvp, (caddr_t)&aitv, + sizeof (struct itimerval)); + if (u.u_error) + return; if (itimerfix(&aitv.it_value) || itimerfix(&aitv.it_interval)) { u.u_error = EINVAL; return; } - s = spl7(); + s = splclock(); if (uap->which == ITIMER_REAL) { - untimeout(realitexpire, p); + untimeout(realitexpire, (caddr_t)p); if (timerisset(&aitv.it_value)) { timevaladd(&aitv.it_value, &time); - timeout(realitexpire, p, hzto(&aitv.it_value)); + timeout(realitexpire, (caddr_t)p, hzto(&aitv.it_value)); } p->p_realtimer = aitv; } else @@ -192,12 +237,12 @@ 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, >)) { - timeout(realitexpire, - p, hzto(&p->p_realtimer.it_value)); + timeout(realitexpire, (caddr_t)p, + hzto(&p->p_realtimer.it_value)); splx(s); return; } @@ -218,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); } @@ -303,74 +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; - if (copyout((caddr_t)&tb, (caddr_t)uap->tp, sizeof(t)) < 0) - u.u_error = EFAULT; -} - -oalarm() -{ - register struct a { - int deltat; - } *uap = (struct a *)u.u_ap; - register struct proc *p = u.u_procp; - struct timeval atv; - int s = spl7(); - - untimeout(realitexpire, 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) { - splx(s); - return; - } - p->p_realtimer.it_value = time; - p->p_realtimer.it_value.tv_sec += uap->deltat; - timeout(realitexpire, p, hzto(&p->p_realtimer.it_value)); - splx(s); -} -#endif