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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).