diff options
author | Artur Grabowski <art@cvs.openbsd.org> | 2002-02-15 01:59:27 +0000 |
---|---|---|
committer | Artur Grabowski <art@cvs.openbsd.org> | 2002-02-15 01:59:27 +0000 |
commit | 18b52be11c9f47bb9190bb894a0f42e14d368257 (patch) | |
tree | 3f09241797d71433d15b46b5072008e62fa9c918 | |
parent | d413aa17549736ce91ba1ac495b270a1f4cfb567 (diff) |
Add a tvtohz function. Like hzto, but doesn't subtract the current time.
-rw-r--r-- | sys/kern/kern_clock.c | 52 | ||||
-rw-r--r-- | sys/sys/systm.h | 3 |
2 files changed, 53 insertions, 2 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 diff --git a/sys/sys/systm.h b/sys/sys/systm.h index 62c097f3533..fe5ec2bf609 100644 --- a/sys/sys/systm.h +++ b/sys/sys/systm.h @@ -1,4 +1,4 @@ -/* $OpenBSD: systm.h,v 1.45 2002/02/04 19:38:20 miod Exp $ */ +/* $OpenBSD: systm.h,v 1.46 2002/02/15 01:59:26 art Exp $ */ /* $NetBSD: systm.h,v 1.50 1996/06/09 04:55:09 briggs Exp $ */ /*- @@ -212,6 +212,7 @@ int suswintr __P((caddr_t, u_int)); struct timeval; int hzto __P((struct timeval *)); +int tvtohz __P((struct timeval *)); void realitexpire __P((void *)); struct clockframe; |