aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/kern_clock.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/kern_clock.c')
-rw-r--r--sys/kern/kern_clock.c82
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);
}