From: Randolph Chung <tausq@debian.org>
To: Linus Torvalds <torvalds@osdl.org>
Cc: Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: Re: [patch] fix __div64_32 to do division properly
Date: Sun, 26 Oct 2003 11:10:20 -0800 [thread overview]
Message-ID: <20031026191020.GL24406@tausq.org> (raw)
In-Reply-To: <Pine.LNX.4.44.0310260931501.934-100000@home.osdl.org>
> As far as I can tell, this one is buggy and can cause total lockups with
> an infinite loop:
oops, you are absolutely right....
your version seems to be ok. i tested it with all two-bit combinations
of dividend and divisors, i.e.
for (b1 = 63; b1 > 0; b1--) {
for (b2 = b1-1; b2 > 0; b2--) {
for (b3 = 31; b3 > 0; b3--) {
for (b4 = b3-1; b4 > 0; b4--) {
dividend = (1ULL<<b1) | (1ULL<<b2);
divisor = (1UL<<b3) | (1UL<<b4);
testdiv(dividend, divisor);
}
}
}
}
and it seems to be ok (and it catches the problem you pointed out). is
that an interesting enough subset? :-)
anyway, here's a new patch tested as above and with the original
nanosleep problem. (i removed the top variable from your version since
it's not used)
thx
randolph
--
Randolph Chung
Debian GNU/Linux Developer, hppa/ia64 ports
http://www.tausq.org/
Index: lib/div64.c
===================================================================
RCS file: /var/cvs/linux-2.6/lib/div64.c,v
retrieving revision 1.1
diff -u -p -r1.1 div64.c
--- lib/div64.c 29 Jul 2003 17:02:19 -0000 1.1
+++ lib/div64.c 26 Oct 2003 19:04:47 -0000
@@ -25,25 +25,34 @@
uint32_t __div64_32(uint64_t *n, uint32_t base)
{
- uint32_t low, low2, high, rem;
+ uint64_t rem = *n;
+ uint64_t b = base;
+ uint64_t res, d = 1;
+ uint32_t high = rem >> 32;
- low = *n & 0xffffffff;
- high = *n >> 32;
- rem = high % (uint32_t)base;
- high = high / (uint32_t)base;
- low2 = low >> 16;
- low2 += rem << 16;
- rem = low2 % (uint32_t)base;
- low2 = low2 / (uint32_t)base;
- low = low & 0xffff;
- low += rem << 16;
- rem = low % (uint32_t)base;
- low = low / (uint32_t)base;
+ /* Reduce the thing a bit first */
+ res = 0;
+ if (high >= base) {
+ high /= base;
+ res = (uint64_t) high << 32;
+ rem -= (uint64_t) (high*base) << 32;
+ }
- *n = low +
- ((uint64_t)low2 << 16) +
- ((uint64_t)high << 32);
+ while ((int64_t)b > 0 && b < rem) {
+ b <<= 1;
+ d <<= 1;
+ }
+ do {
+ if (rem >= b) {
+ rem -= b;
+ res += d;
+ }
+ b >>= 1;
+ d >>= 1;
+ } while (d);
+
+ *n = res;
return rem;
}
next prev parent reply other threads:[~2003-10-26 19:06 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20031026152412.GK24406@tausq.org>
2003-10-26 18:01 ` [patch] fix __div64_32 to do division properly Linus Torvalds
2003-10-26 19:10 ` Randolph Chung [this message]
2003-10-24 4:20 Randolph Chung
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20031026191020.GL24406@tausq.org \
--to=tausq@debian.org \
--cc=linux-kernel@vger.kernel.org \
--cc=torvalds@osdl.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.