Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/external/bsd/common/include/linux Give find_first/next_s...



details:   https://anonhg.NetBSD.org/src/rev/410879d160af
branches:  trunk
changeset: 366311:410879d160af
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Mon Aug 27 14:46:23 2018 +0000

description:
Give find_first/next_set/zero_bit a chance to work.

Self-review comments on the draft thrown together in a hurry two
weeks ago:

- I bet I screwed up for_each_set_bit or something.
- There might be several bits wrong in this __find_next_bit routine!
- for_each_set_bit is busted.
- Maybe I should test this stuff before I commit it.
- Hey, cool, buffer overflow here.
- What was I thinking.
- how did this even
- Was I drunk?  I'm never drunk.
- I don't even drink.
- It wasn't even that late at night...

diffstat:

 sys/external/bsd/common/include/linux/bitops.h |  54 ++++++++++++++-----------
 1 files changed, 31 insertions(+), 23 deletions(-)

diffs (83 lines):

diff -r 1fd80497040a -r 410879d160af sys/external/bsd/common/include/linux/bitops.h
--- a/sys/external/bsd/common/include/linux/bitops.h    Mon Aug 27 14:46:10 2018 +0000
+++ b/sys/external/bsd/common/include/linux/bitops.h    Mon Aug 27 14:46:23 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: bitops.h,v 1.7 2018/08/27 13:54:37 riastradh Exp $     */
+/*     $NetBSD: bitops.h,v 1.8 2018/08/27 14:46:23 riastradh Exp $     */
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -188,7 +188,8 @@
 {
        const size_t bpl = (CHAR_BIT * sizeof(*ptr));
        const unsigned long *p = ptr + startbit/bpl;
-       unsigned long result = rounddown(startbit, bpl);
+       size_t n = howmany(nbits, bpl);
+       unsigned long result;
        uint64_t word;
 
        /*
@@ -200,35 +201,42 @@
 
        /* Do we need to examine a partial starting word?  */
        if (startbit % bpl) {
-               /* Are any of the first startbit%bpl bits zero?  */
-               if ((*p ^ toggle) & ~(~0UL << (startbit % bpl))) {
-                       /* Toggle the bits and convert to 64 bits.  */
-                       word = *p ^ toggle;
+               /* Toggle the bits and convert to 64 bits for ffs64.  */
+               word = *p ^ toggle;
+
+               /* Clear the low startbit%bpl bits.  */
+               word &= (~0UL << (startbit % bpl));
 
-                       /* Clear the low startbit%bpl bits.  */
-                       word &= ~(~0UL << (startbit % bpl));
+               /* Are any of these bits set now?  */
+               if (word)
+                       goto out;
 
-                       /* Find the first set bit in this word. */
-                       result += ffs64(word);
-
-                       /* Clamp down to at most nbits.  */
-                       return MIN(result, nbits);
-               }
+               /* Move past it.  */
+               p++;
+               n--;
        }
 
-       /* Find the first word matching word.  */
-       for (; bpl < nbits; p++, result += bpl) {
-               if (*p ^ toggle)
-                       break;
+       /* Find the first word with any bits set.  */
+       for (; n --> 0; p++) {
+               /* Toggle the bits and convert to 64 bits for ffs64. */
+               word = *p ^ toggle;
+
+               /* Are any of these bits set now?  */
+               if (word)
+                       goto out;
        }
 
-       /* Toggle the bits and convert to 64 bits for ffs64.  */
-       word = *p ^ toggle;
+       /* Nada.  */
+       return nbits;
 
-       /* Find the first set bit in this word.  */
-       result += ffs64(word);
+out:
+       /* Count how many words we've skipped.  */
+       result = bpl*(p - ptr);
 
-       /* Clamp down to at most nbits.  */
+       /* Find the first set bit in this word, zero-based.  */
+       result += ffs64(word) - 1;
+
+       /* We may have overshot, so clamp down to at most nbits.  */
        return MIN(result, nbits);
 }
 



Home | Main Index | Thread Index | Old Index