Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 15 Jul 2003 08:04:00 +1000 (EST)
From:      Bruce Evans <bde@zeta.org.au>
To:        Josef Karthauser <joe@freebsd.org>
Cc:        arch@freebsd.org
Subject:   Re: Importing 'mstohz' from NetBSD.
Message-ID:  <20030715072847.S9776@gamplex.bde.org>
In-Reply-To: <20030714190514.GA3270@genius.tao.org.uk>
References:  <20030714190514.GA3270@genius.tao.org.uk>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, 14 Jul 2003, Josef Karthauser wrote:

> It looks like NetBSD have a net function defined in the kernel.
>
>     --- param.h	2002/03/17 19:43:07	1.137
>     +++ param.h	2002/04/05 18:27:57	1.138
>     @@ -1,4 +1,4 @@
>     -/*	$NetBSD: param.h,v 1.136 2002/03/09 01:42:13 thorpej Exp $	*/
>     +/*	$NetBSD: param.h,v 1.137 2002/03/17 19:43:07 atatat Exp $	*/
>
>      /*-
>       * Copyright (c) 1982, 1986, 1989, 1993
>     @@ -274,5 +274,20 @@
>      #ifndef UBC_NWINS
>      #define	UBC_NWINS	1024
>      #endif
>     +
>     +#ifdef _KERNEL
>     +/*
>     + * macro to convert from milliseconds to hz without integer overflow
>     + * Default version using only 32bits arithmetics.
>     + * 64bit port can define 64bit version in their <machine/param.h>
>     + * 0x20000 is safe for hz < 20000
>     + */
>     +#ifndef mstohz
>     +#define mstohz(ms) \
>     +	(__predict_false((ms) >= 0x20000) ? \
>     +	    ((ms +0u) / 1000u) * hz : \
>     +	    ((ms +0u) * hz) / 1000u)
>     +#endif
>     +#endif /* _KERNEL */
>
>      #endif /* !_SYS_PARAM_H_ */
>
> They have replaced TICKS_TO_HZ with calls to 'mstohz' in the usb stack
> as well as in other places.  Is this something that we want to do also?

I think you mean a new function that replaces the usb-specific macro
MS_TO_TICKS() by general interface named mstohz().  (The new interface
is no different except for its name, but its implementation doesn't
give undefined behaviour on overflow.)

I think the new interface should be kept in usb for now.  The kernel has
to many representations of times, and milliseconds is not particularly
common, convenient or good.

The macro shouldn't be defined in <sys/param.h> since it is not a parameter;
it is only defined there to give it global scope.  I wouldn't bother
micro-optimizing it, including making it a macro instead of a function; it
is probably not needed in [m]any fast paths, and the multiplications and
divisions in it probably take longer than function a call.  Anyway, we
don't bother micro-optimizing the similar tvtohz() function.  NetBSD
doesn't seem to have tvtohz(), but it has the slightly different hzto()
function with a similar implementation optimized for correctness more
than speed.  The non-(time-)optimization of these functions hasn't
proved to be noticeable.  tvtohz() is more than slightly easier to use
than hzto(); mstohz() can easily be implemented on top of hzto() by
converting from millseconds to a timeval and passing the timeval to
tvtohz().  This would give a very correct implementation in a simple
way at some cost in efficiency.

Starting from scratch, I would use common units much smaller than a
1/hz tick or a millisecond for most times in the kernel.  Old interfaces
like timeout() still get some benefits on some machines by using only
32-bit counters, but these benefits will become negative when 32-bit
machine go away.

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030715072847.S9776>