linux-mips
[Top] [All Lists]

possible overflow in __udelay

To: linux-mips@linux-mips.org
Subject: possible overflow in __udelay
From: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Date: Thu, 01 Jul 2004 21:14:56 +0900 (JST)
Original-recipient: rfc822;linux-mips@linux-mips.org
Sender: linux-mips-bounce@linux-mips.org
Current __udelay implementation will cause internal overflow on the
first multiplication.

Basically, the multiplication is:

X = usecs * 2**64 / (100000 / HZ)

And maximum input usecs value is 5000 (MAX_UDELAY_MS * 1000).

If usecs == 5000 and HZ == 1000, X is 5 * 2**64.  Of course this can
not be held in 64bit variable.

How should we avoid the overflow?


1. Use smaller HZ.

HZ < 200 should be OK.


2. Use smaller MAX_UDELAY_MS.

The arch specific delay.h can provide its own MAX_UDELAY_MS.
MAX_UDELAY_MS == 1 should be OK.


3. Use smaller multiplier.

This example should be OK (but lose some precision on larger HZ)

#if HZ < (1000 / MAX_UDELAY_MS)
        usecs *= (0x8000000000000000UL / (500000 / HZ));
#elif HZ < ((1000 / MAX_UDELAY_MS) << 1)
        usecs *= (0x8000000000000000UL / (500000 / HZ)) >> 1;
        lpj <<= 1
#elif HZ < ((1000 / MAX_UDELAY_MS) << 2)
        usecs *= (0x8000000000000000UL / (500000 / HZ)) >> 2;
        lpj <<= 2
#else
        usecs *= (0x8000000000000000UL / (500000 / HZ)) >> 3;
        lpj <<= 3
#endif


Any idea?

---
Atsushi Nemoto

<Prev in Thread] Current Thread [Next in Thread>