summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorArtur Grabowski <art@cvs.openbsd.org>2002-02-15 01:59:27 +0000
committerArtur Grabowski <art@cvs.openbsd.org>2002-02-15 01:59:27 +0000
commit18b52be11c9f47bb9190bb894a0f42e14d368257 (patch)
tree3f09241797d71433d15b46b5072008e62fa9c918 /sys/kern
parentd413aa17549736ce91ba1ac495b270a1f4cfb567 (diff)
Add a tvtohz function. Like hzto, but doesn't subtract the current time.
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_clock.c52
1 files changed, 51 insertions, 1 deletions
diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c
index 0b7dfd3fe9e..6e6f0e3cca5 100644
--- a/sys/kern/kern_clock.c
+++ b/sys/kern/kern_clock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_clock.c,v 1.31 2002/01/02 06:07:41 nordin Exp $ */
+/* $OpenBSD: kern_clock.c,v 1.32 2002/02/15 01:59:26 art Exp $ */
/* $NetBSD: kern_clock.c,v 1.34 1996/06/09 04:51:03 briggs Exp $ */
/*-
@@ -764,6 +764,56 @@ hzto(tv)
}
/*
+ * Compute number of hz in the specified amount of time.
+ */
+int
+tvtohz(struct timeval *tv)
+{
+ unsigned long ticks;
+ long sec, usec;
+
+ /*
+ * 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.
+ *
+ * If ints have 32 bits, then the maximum value for any timeout in
+ * 10ms ticks is 248 days.
+ */
+ sec = tv->tv_sec;
+ usec = tv->tv_usec;
+ if (usec < 0) {
+ sec--;
+ usec += 1000000;
+ }
+ if (sec < 0 || (sec == 0 && usec <= 0)) {
+ ticks = 0;
+ } 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;
+ if (ticks > INT_MAX)
+ ticks = INT_MAX;
+ return ((int)ticks);
+}
+
+/*
* Start profiling on a process.
*
* Kernel profiling passes proc0 which never exits and hence