diff options
Diffstat (limited to 'sys/kern/kern_clock.c')
| -rw-r--r-- | sys/kern/kern_clock.c | 82 |
1 files changed, 62 insertions, 20 deletions
diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c index eca7041a3e35..44a334e00ebc 100644 --- a/sys/kern/kern_clock.c +++ b/sys/kern/kern_clock.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)kern_clock.c 7.16 (Berkeley) 5/9/91 - * $Id: kern_clock.c,v 1.6 1993/10/25 02:02:51 davidg Exp $ + * $Id: kern_clock.c,v 1.11 1993/12/19 00:51:20 wollman Exp $ */ #include "param.h" @@ -40,6 +40,7 @@ #include "callout.h" #include "kernel.h" #include "proc.h" +#include "signalvar.h" #include "resourcevar.h" #include "machine/cpu.h" @@ -51,6 +52,12 @@ #include "gprof.h" #endif +static void gatherstats(clockframe *); + +/* From callout.h */ +struct callout *callfree, *callout, calltodo; +int ncallout; + /* * Clock handling routines. * @@ -91,12 +98,13 @@ * If this timer is also being used to gather statistics, * we run through the statistics gathering routine as well. */ +void hardclock(frame) clockframe frame; { register struct callout *p1; register struct proc *p = curproc; - register struct pstats *pstats; + register struct pstats *pstats = 0; register struct rusage *ru; register struct vmspace *vm; register int s; @@ -282,6 +290,7 @@ int dk_ndrive = DK_NDRIVE; * or idle state) for the entire last time interval, and * update statistics accordingly. */ +void gatherstats(framep) clockframe *framep; { @@ -335,6 +344,7 @@ gatherstats(framep) * Run periodic events from timeout queue. */ /*ARGSUSED*/ +void softclock(frame) clockframe frame; { @@ -342,7 +352,7 @@ softclock(frame) for (;;) { register struct callout *p1; register caddr_t arg; - register int (*func)(); + register timeout_func_t func; register int a, s; s = splhigh(); @@ -389,8 +399,9 @@ softclock(frame) /* * Arrange that (*func)(arg) is called in t/hz seconds. */ +void timeout(func, arg, t) - int (*func)(); + timeout_func_t func; caddr_t arg; register int t; { @@ -420,8 +431,9 @@ timeout(func, arg, t) * untimeout is called to remove a function timeout call * from the callout structure. */ +void untimeout(func, arg) - int (*func)(); + timeout_func_t func; caddr_t arg; { register struct callout *p1, *p2; @@ -446,30 +458,60 @@ untimeout(func, arg) * Used to compute third argument to timeout() from an * absolute time. */ + +/* XXX clock_t */ +u_long hzto(tv) struct timeval *tv; { - register long ticks; + register unsigned long ticks; register long sec; - int s = splhigh(); + register long usec; + int s; /* - * If number of milliseconds will fit in 32 bit arithmetic, - * then compute number of milliseconds to time and scale to - * ticks. Otherwise just compute number of hz in time, rounding - * times greater than representible to maximum value. + * If the number of usecs in the whole seconds part of the time + * difference fits in a long, then the total number of usecs will + * fit in an unsigned long. Compute the total and convert it to + * ticks, rounding up and adding 1 to allow for the current tick + * to expire. Rounding also depends on unsigned long arithmetic + * to avoid overflow. + * + * Otherwise, if the number of ticks in the whole seconds part of + * the time difference fits in a long, then convert the parts to + * ticks separately and add, using similar rounding methods and + * overflow avoidance. This method would work in the previous + * case but it is slightly slower and assumes that hz is integral. + * + * Otherwise, round the time difference down to the maximum + * representable value. * - * Delta times less than 25 days can be computed ``exactly''. - * Maximum value for any timeout in 10ms ticks is 250 days. + * Maximum value for any timeout in 10ms ticks is 248 days. */ + s = splhigh(); sec = tv->tv_sec - time.tv_sec; - if (sec <= 0x7fffffff / 1000 - 1000) - ticks = ((tv->tv_sec - time.tv_sec) * 1000 + - (tv->tv_usec - time.tv_usec) / 1000) / (tick / 1000); - else if (sec <= 0x7fffffff / hz) - ticks = sec * hz; - else - ticks = 0x7fffffff; + usec = tv->tv_usec - time.tv_usec; splx(s); + if (usec < 0) { + sec--; + usec += 1000000; + } + if (sec < 0) { +#ifdef DIAGNOSTIC + printf("hzto: negative time difference %ld sec %ld usec\n", + sec, usec); +#endif + ticks = 1; + } else if (sec <= LONG_MAX / 1000000) + ticks = (sec * 1000000 + (unsigned long)usec + (tick - 1)) + / tick + 1; + else if (sec <= LONG_MAX / hz) + ticks = sec * hz + + ((unsigned long)usec + (tick - 1)) / tick + 1; + else + ticks = LONG_MAX; +#define CLOCK_T_MAX INT_MAX /* XXX should be ULONG_MAX */ + if (ticks > CLOCK_T_MAX) + ticks = CLOCK_T_MAX; return (ticks); } |
