[PATCH] bitops: simplify generic bit finding functions

!MAILaRCHIVE_VOTE_RePLACE
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
To: Ingo Molnar <mingo@...>, Linus Torvalds <torvalds@...>
Cc: Andrew Morton <akpm@...>, LKML <linux-kernel@...>
Date: Sunday, April 27, 2008 - 4:19 pm

No need for a sentinal if we explicitly catch the no bits/all bits set
cases, make it clear they are special cases returning size/BITS_PER_LONG.

Signed-off-by: Harvey Harrison <harvey.harrison@gmail.com>
---
 include/linux/bitops.h |   93 ++++++++++++++++++++----------------------------
 1 files changed, 39 insertions(+), 54 deletions(-)

diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index 48bde60..d9eb58a 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -127,18 +127,17 @@ extern unsigned long __find_first_bit(const unsigned long *addr,
 static __always_inline unsigned long
 find_first_bit(const unsigned long *addr, unsigned long size)
 {
-	/* Avoid a function call if the bitmap size is a constant */
-	/* and not bigger than BITS_PER_LONG. */
-
-	/* insert a sentinel so that __ffs returns size if there */
-	/* are no set bits in the bitmap */
-	if (__builtin_constant_p(size) && (size < BITS_PER_LONG))
-		return __ffs((*addr) | (1ul << size));
-
-	/* the result of __ffs(0) is undefined, so it needs to be */
-	/* handled separately */
-	if (__builtin_constant_p(size) && (size == BITS_PER_LONG))
-		return ((*addr) == 0) ? BITS_PER_LONG : __ffs(*addr);
+	/*
+	 * Avoid a function call if the bitmap size is a constant and not
+	 * bigger than BITS_PER_LONG.  Ensure we return size if there are
+	 * no set bits.
+	 */
+	if (__builtin_constant_p(size) && (size <= BITS_PER_LONG)) {
+		if (*addr == 0)
+			return (size < BITS_PER_LONG) ? size : BITS_PER_LONG;
+		else
+			return __ffs(*addr);
+	}
 
 	/* size is not constant or too big */
 	return __find_first_bit(addr, size);
@@ -157,20 +156,17 @@ extern unsigned long __find_first_zero_bit(const unsigned long *addr,
 static __always_inline unsigned long
 find_first_zero_bit(const unsigned long *addr, unsigned long size)
 {
-	/* Avoid a function call if the bitmap size is a constant */
-	/* and not bigger than BITS_PER_LONG. */
-
-	/* insert a sentinel so that __ffs returns size if there */
-	/* are no set bits in the bitmap */
-	if (__builtin_constant_p(size) && (size < BITS_PER_LONG)) {
-		return __ffs(~(*addr) | (1ul << size));
+	/*
+	 * Avoid a function call if the bitmap size is a constant and not
+	 * bigger than BITS_PER_LONG.  Ensure we return size if all bits set.
+	 */
+	if (__builtin_constant_p(size) && (size <= BITS_PER_LONG)) {
+		if ((~(*addr)) == 0)
+			return (size < BITS_PER_LONG) ? size : BITS_PER_LONG;
+		else
+			return __ffs(~(*addr));
 	}
 
-	/* the result of __ffs(0) is undefined, so it needs to be */
-	/* handled separately */
-	if (__builtin_constant_p(size) && (size == BITS_PER_LONG))
-		return (~(*addr) == 0) ? BITS_PER_LONG : __ffs(~(*addr));
-
 	/* size is not constant or too big */
 	return __find_first_zero_bit(addr, size);
 }
@@ -192,22 +188,17 @@ find_next_bit(const unsigned long *addr, unsigned long size,
 {
 	unsigned long value;
 
-	/* Avoid a function call if the bitmap size is a constant */
-	/* and not bigger than BITS_PER_LONG. */
-
-	/* insert a sentinel so that __ffs returns size if there */
-	/* are no set bits in the bitmap */
-	if (__builtin_constant_p(size) && (size < BITS_PER_LONG)) {
+	/*
+	 * Avoid a function call if the bitmap size is a constant and not
+	 * bigger than BITS_PER_LONG.  Ensure we return size if there are
+	 * no set bits.
+	 */
+	if (__builtin_constant_p(size) && (size <= BITS_PER_LONG)) {
 		value = (*addr) & ((~0ul) << offset);
-		value |= (1ul << size);
-		return __ffs(value);
-	}
-
-	/* the result of __ffs(0) is undefined, so it needs to be */
-	/* handled separately */
-	if (__builtin_constant_p(size) && (size == BITS_PER_LONG)) {
-		value = (*addr) & ((~0ul) << offset);
-		return (value == 0) ? BITS_PER_LONG : __ffs(value);
+		if (value == 0)
+			return (size < BITS_PER_LONG) ? size : BITS_PER_LONG;
+		else
+			return __ffs(value);
 	}
 
 	/* size is not constant or too big */
@@ -229,22 +220,16 @@ find_next_zero_bit(const unsigned long *addr, unsigned long size,
 {
 	unsigned long value;
 
-	/* Avoid a function call if the bitmap size is a constant */
-	/* and not bigger than BITS_PER_LONG. */
-
-	/* insert a sentinel so that __ffs returns size if there */
-	/* are no set bits in the bitmap */
-	if (__builtin_constant_p(size) && (size < BITS_PER_LONG)) {
-		value = (~(*addr)) & ((~0ul) << offset);
-		value |= (1ul << size);
-		return __ffs(value);
-	}
-
-	/* the result of __ffs(0) is undefined, so it needs to be */
-	/* handled separately */
-	if (__builtin_constant_p(size) && (size == BITS_PER_LONG)) {
+	/*
+	 * Avoid a function call if the bitmap size is a constant and not
+	 * bigger than BITS_PER_LONG.  Ensure we return size if all bits set.
+	 */
+	if (__builtin_constant_p(size) && (size <= BITS_PER_LONG)) {
 		value = (~(*addr)) & ((~0ul) << offset);
-		return (value == 0) ? BITS_PER_LONG : __ffs(value);
+		if (value == 0)
+			return (size < BITS_PER_LONG) ? size : BITS_PER_LONG;
+		else
+			return __ffs(value);
 	}
 
 	/* size is not constant or too big */
-- 
1.5.5.1.270.g89765



--
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
[PATCH] bitops: simplify generic bit finding functions, Harvey Harrison, (Sun Apr 27, 4:19 pm)
Re: [PATCH] bitops: simplify generic bit finding functions, Alexander van Heukelum, (Mon Apr 28, 10:32 am)
Re: [PATCH] bitops: simplify generic bit finding functions, Linus Torvalds, (Sun Apr 27, 4:26 pm)
Re: [PATCH] bitops: simplify generic bit finding functions, Alexander van Heukelum, (Mon Apr 28, 10:58 am)
Re: [PATCH] bitops: simplify generic bit finding functions, Thomas Gleixner, (Mon Apr 28, 10:04 am)
Re: [PATCH] bitops: simplify generic bit finding functions, Linus Torvalds, (Mon Apr 28, 12:25 pm)
Re: [PATCH] bitops: simplify generic bit finding functions, Thomas Gleixner, (Mon Apr 28, 12:47 pm)
Re: [PATCH] bitops: simplify generic bit finding functions, Linus Torvalds, (Mon Apr 28, 12:54 pm)
Re: [PATCH] bitops: simplify generic bit finding functions, Thomas Gleixner, (Mon Apr 28, 3:26 pm)
Re: [PATCH] bitops: simplify generic bit finding functions, Linus Torvalds, (Mon Apr 28, 3:37 pm)
[PATCH] bitops: remove "optimizations", Thomas Gleixner, (Tue Apr 29, 6:01 am)
Re: [PATCH] bitops: remove "optimizations", David Miller, (Tue Apr 29, 6:03 am)
Re: [PATCH] bitops: remove "optimizations", David Miller, (Tue Apr 29, 8:34 am)
Re: [PATCH] bitops: remove "optimizations", Thomas Gleixner, (Tue Apr 29, 12:51 pm)
Re: [PATCH] bitops: remove "optimizations", David Miller, (Tue Apr 29, 6:58 pm)
Re: [PATCH] bitops: remove "optimizations", David Miller, (Tue Apr 29, 7:30 pm)
Re: [PATCH] bitops: remove "optimizations", Ingo Molnar, (Tue Apr 29, 10:20 am)
Re: [PATCH] bitops: remove "optimizations", David Miller, (Tue Apr 29, 6:31 pm)
Re: [PATCH] bitops: simplify generic bit finding functions, Alexander van Heukelum, (Mon Apr 28, 11:10 am)
Re: [PATCH] bitops: simplify generic bit finding functions, Thomas Gleixner, (Mon Apr 28, 11:58 am)
Re: [PATCH] bitops: simplify generic bit finding functions, Harvey Harrison, (Sun Apr 27, 4:29 pm)
Re: [PATCH] bitops: simplify generic bit finding functions, Linus Torvalds, (Sun Apr 27, 4:38 pm)
Re: [PATCH] bitops: simplify generic bit finding functions, Harvey Harrison, (Sun Apr 27, 4:38 pm)