* [patch 07/47] generic __{, test_and_}{set, clear, change}_bit() and test_bit()
[not found] <20060214050351.252615000@localhost.localdomain>
@ 2006-02-14 5:03 ` Akinobu Mita
2006-02-14 5:04 ` [patch 11/47] generic fls64() Akinobu Mita
` (3 subsequent siblings)
4 siblings, 0 replies; 5+ messages in thread
From: Akinobu Mita @ 2006-02-14 5:03 UTC (permalink / raw)
To: linux-kernel
Cc: akpm, linux-mips, dev-etrax, ultralinux, Ian Molton,
Hirokazu Takata, Akinobu Mita, linuxppc-dev, linuxsh-dev,
sparclinux, Chris Zankel, linuxsh-shmedia-dev, Russell King,
parisc-linux
This patch introduces the C-language equivalents of the functions below:
void __set_bit(int nr, volatile unsigned long *addr);
void __clear_bit(int nr, volatile unsigned long *addr);
void __change_bit(int nr, volatile unsigned long *addr);
int __test_and_set_bit(int nr, volatile unsigned long *addr);
int __test_and_clear_bit(int nr, volatile unsigned long *addr);
int __test_and_change_bit(int nr, volatile unsigned long *addr);
int test_bit(int nr, const volatile unsigned long *addr);
In include/asm-generic/bitops/non-atomic.h
This code largely copied from:
asm-powerpc/bitops.h
Signed-off-by: Akinobu Mita <mita@miraclelinux.com>
include/asm-generic/bitops/non-atomic.h | 111 ++++++++++++++++++++++++++++++++
1 files changed, 111 insertions(+)
Index: 2.6-rc/include/asm-generic/bitops/non-atomic.h
===================================================================
--- /dev/null
+++ 2.6-rc/include/asm-generic/bitops/non-atomic.h
@@ -0,0 +1,111 @@
+#ifndef _ASM_GENERIC_BITOPS_NON_ATOMIC_H_
+#define _ASM_GENERIC_BITOPS_NON_ATOMIC_H_
+
+#include <asm/types.h>
+
+#define BITOP_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
+#define BITOP_WORD(nr) ((nr) / BITS_PER_LONG)
+
+/**
+ * __set_bit - Set a bit in memory
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ *
+ * Unlike set_bit(), this function is non-atomic and may be reordered.
+ * If it's called on the same region of memory simultaneously, the effect
+ * may be that only one operation succeeds.
+ */
+static inline void __set_bit(int nr, volatile unsigned long *addr)
+{
+ unsigned long mask = BITOP_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+
+ *p |= mask;
+}
+
+static inline void __clear_bit(int nr, volatile unsigned long *addr)
+{
+ unsigned long mask = BITOP_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+
+ *p &= ~mask;
+}
+
+/**
+ * __change_bit - Toggle a bit in memory
+ * @nr: the bit to change
+ * @addr: the address to start counting from
+ *
+ * Unlike change_bit(), this function is non-atomic and may be reordered.
+ * If it's called on the same region of memory simultaneously, the effect
+ * may be that only one operation succeeds.
+ */
+static inline void __change_bit(int nr, volatile unsigned long *addr)
+{
+ unsigned long mask = BITOP_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+
+ *p ^= mask;
+}
+
+/**
+ * __test_and_set_bit - Set a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is non-atomic and can be reordered.
+ * If two examples of this operation race, one can appear to succeed
+ * but actually fail. You must protect multiple accesses with a lock.
+ */
+static inline int __test_and_set_bit(int nr, volatile unsigned long *addr)
+{
+ unsigned long mask = BITOP_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+ unsigned long old = *p;
+
+ *p = old | mask;
+ return (old & mask) != 0;
+}
+
+/**
+ * __test_and_clear_bit - Clear a bit and return its old value
+ * @nr: Bit to clear
+ * @addr: Address to count from
+ *
+ * This operation is non-atomic and can be reordered.
+ * If two examples of this operation race, one can appear to succeed
+ * but actually fail. You must protect multiple accesses with a lock.
+ */
+static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
+{
+ unsigned long mask = BITOP_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+ unsigned long old = *p;
+
+ *p = old & ~mask;
+ return (old & mask) != 0;
+}
+
+/* WARNING: non atomic and it can be reordered! */
+static inline int __test_and_change_bit(int nr,
+ volatile unsigned long *addr)
+{
+ unsigned long mask = BITOP_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+ unsigned long old = *p;
+
+ *p = old ^ mask;
+ return (old & mask) != 0;
+}
+
+/**
+ * test_bit - Determine whether a bit is set
+ * @nr: bit number to test
+ * @addr: Address to start counting from
+ */
+static inline int test_bit(int nr, const volatile unsigned long *addr)
+{
+ return 1UL & (addr[BITOP_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
+}
+
+#endif /* _ASM_GENERIC_BITOPS_NON_ATOMIC_H_ */
--
^ permalink raw reply [flat|nested] 5+ messages in thread* [patch 11/47] generic fls64()
[not found] <20060214050351.252615000@localhost.localdomain>
2006-02-14 5:03 ` [patch 07/47] generic __{, test_and_}{set, clear, change}_bit() and test_bit() Akinobu Mita
@ 2006-02-14 5:04 ` Akinobu Mita
2006-02-14 5:04 ` [patch 13/47] generic sched_find_first_bit() Akinobu Mita
` (2 subsequent siblings)
4 siblings, 0 replies; 5+ messages in thread
From: Akinobu Mita @ 2006-02-14 5:04 UTC (permalink / raw)
To: linux-kernel
Cc: akpm, linux-mips, linux-ia64, Ian Molton, Andi Kleen,
David Howells, linuxppc-dev, Greg Ungerer, sparclinux,
Miles Bader, Yoshinori Sato, Hirokazu Takata, linuxsh-shmedia-dev,
linux-m68k, Ivan Kokshaysky, Richard Henderson, Akinobu Mita,
Chris Zankel, dev-etrax, ultralinux, Linus Torvalds, linuxsh-dev,
linux390, Russell King, parisc-linux
This patch introduces the C-language equivalent of the function:
int fls64(__u64 x);
In include/asm-generic/bitops/fls64.h
This code largely copied from:
include/linux/bitops.h
Signed-off-by: Akinobu Mita <mita@miraclelinux.com>
include/asm-generic/bitops/fls64.h | 12 ++++++++++++
1 files changed, 12 insertions(+)
Index: 2.6-rc/include/asm-generic/bitops/fls64.h
===================================================================
--- /dev/null
+++ 2.6-rc/include/asm-generic/bitops/fls64.h
@@ -0,0 +1,12 @@
+#ifndef _ASM_GENERIC_BITOPS_FLS64_H_
+#define _ASM_GENERIC_BITOPS_FLS64_H_
+
+static inline int fls64(__u64 x)
+{
+ __u32 h = x >> 32;
+ if (h)
+ return fls(h) + 32;
+ return fls(x);
+}
+
+#endif /* _ASM_GENERIC_BITOPS_FLS64_H_ */
--
^ permalink raw reply [flat|nested] 5+ messages in thread* [patch 13/47] generic sched_find_first_bit()
[not found] <20060214050351.252615000@localhost.localdomain>
2006-02-14 5:03 ` [patch 07/47] generic __{, test_and_}{set, clear, change}_bit() and test_bit() Akinobu Mita
2006-02-14 5:04 ` [patch 11/47] generic fls64() Akinobu Mita
@ 2006-02-14 5:04 ` Akinobu Mita
2006-02-14 5:04 ` [patch 15/47] generic hweight{64,32,16,8}() Akinobu Mita
2006-02-14 5:04 ` [patch 32/47] powerpc: use generic bitops Akinobu Mita
4 siblings, 0 replies; 5+ messages in thread
From: Akinobu Mita @ 2006-02-14 5:04 UTC (permalink / raw)
To: linux-kernel
Cc: akpm, linux-mips, linux-ia64, Ian Molton, David Howells,
linuxppc-dev, Greg Ungerer, sparclinux, Miles Bader,
Linus Torvalds, Yoshinori Sato, Hirokazu Takata, linuxsh-dev,
linux-m68k, Akinobu Mita, Chris Zankel, dev-etrax, ultralinux,
Andi Kleen, linuxsh-shmedia-dev, linux390, Russell King,
parisc-linux
This patch introduces the C-language equivalent of the function:
int sched_find_first_bit(const unsigned long *b);
In include/asm-generic/bitops/sched.h
This code largely copied from:
include/asm-powerpc/bitops.h
Signed-off-by: Akinobu Mita <mita@miraclelinux.com>
include/asm-generic/bitops/sched.h | 36 ++++++++++++++++++++++++++++++++++++
1 files changed, 36 insertions(+)
Index: 2.6-rc/include/asm-generic/bitops/sched.h
===================================================================
--- /dev/null
+++ 2.6-rc/include/asm-generic/bitops/sched.h
@@ -0,0 +1,36 @@
+#ifndef _ASM_GENERIC_BITOPS_SCHED_H_
+#define _ASM_GENERIC_BITOPS_SCHED_H_
+
+#include <linux/compiler.h> /* unlikely() */
+#include <asm/types.h>
+
+/*
+ * Every architecture must define this function. It's the fastest
+ * way of searching a 140-bit bitmap where the first 100 bits are
+ * unlikely to be set. It's guaranteed that at least one of the 140
+ * bits is cleared.
+ */
+static inline int sched_find_first_bit(const unsigned long *b)
+{
+#if BITS_PER_LONG == 64
+ if (unlikely(b[0]))
+ return __ffs(b[0]);
+ if (unlikely(b[1]))
+ return __ffs(b[1]) + 64;
+ return __ffs(b[2]) + 128;
+#elif BITS_PER_LONG == 32
+ if (unlikely(b[0]))
+ return __ffs(b[0]);
+ if (unlikely(b[1]))
+ return __ffs(b[1]) + 32;
+ if (unlikely(b[2]))
+ return __ffs(b[2]) + 64;
+ if (b[3])
+ return __ffs(b[3]) + 96;
+ return __ffs(b[4]) + 128;
+#else
+#error BITS_PER_LONG not defined
+#endif
+}
+
+#endif /* _ASM_GENERIC_BITOPS_SCHED_H_ */
--
^ permalink raw reply [flat|nested] 5+ messages in thread* [patch 15/47] generic hweight{64,32,16,8}()
[not found] <20060214050351.252615000@localhost.localdomain>
` (2 preceding siblings ...)
2006-02-14 5:04 ` [patch 13/47] generic sched_find_first_bit() Akinobu Mita
@ 2006-02-14 5:04 ` Akinobu Mita
2006-02-14 5:04 ` [patch 32/47] powerpc: use generic bitops Akinobu Mita
4 siblings, 0 replies; 5+ messages in thread
From: Akinobu Mita @ 2006-02-14 5:04 UTC (permalink / raw)
To: linux-kernel
Cc: akpm, linux-mips, linux-ia64, Ian Molton, Andi Kleen,
David Howells, linuxppc-dev, Greg Ungerer, sparclinux,
Miles Bader, Yoshinori Sato, Hirokazu Takata, linuxsh-shmedia-dev,
linux-m68k, Ivan Kokshaysky, Richard Henderson, Akinobu Mita,
Chris Zankel, dev-etrax, ultralinux, Linus Torvalds, linuxsh-dev,
linux390, Russell King, parisc-linux
This patch introduces the C-language equivalents of the functions below:
unsigned int hweight32(unsigned int w);
unsigned int hweight16(unsigned int w);
unsigned int hweight8(unsigned int w);
unsigned long hweight64(__u64 w);
In include/asm-generic/bitops/hweight.h
This code largely copied from:
include/linux/bitops.h
Signed-off-by: Akinobu Mita <mita@miraclelinux.com>
include/asm-generic/bitops/hweight.h | 9 +++++
lib/Makefile | 1
lib/hweight.c | 54 +++++++++++++++++++++++++++++++++++
3 files changed, 64 insertions(+)
Index: 2.6-rc/include/asm-generic/bitops/hweight.h
===================================================================
--- /dev/null
+++ 2.6-rc/include/asm-generic/bitops/hweight.h
@@ -0,0 +1,9 @@
+#ifndef _ASM_GENERIC_BITOPS_HWEIGHT_H_
+#define _ASM_GENERIC_BITOPS_HWEIGHT_H_
+
+extern unsigned int hweight32(unsigned int w);
+extern unsigned int hweight16(unsigned int w);
+extern unsigned int hweight8(unsigned int w);
+extern unsigned long hweight64(__u64 w);
+
+#endif /* _ASM_GENERIC_BITOPS_HWEIGHT_H_ */
Index: 2.6-rc/lib/Makefile
===================================================================
--- 2.6-rc.orig/lib/Makefile
+++ 2.6-rc/lib/Makefile
@@ -21,6 +21,7 @@ lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) +=
lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o
lib-$(CONFIG_SEMAPHORE_SLEEPERS) += semaphore-sleepers.o
lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find_next_bit.o
+lib-$(CONFIG_GENERIC_HWEIGHT) += hweight.o
obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o
obj-$(CONFIG_DEBUG_PREEMPT) += smp_processor_id.o
Index: 2.6-rc/lib/hweight.c
===================================================================
--- /dev/null
+++ 2.6-rc/lib/hweight.c
@@ -0,0 +1,54 @@
+#include <linux/module.h>
+#include <asm/types.h>
+
+/**
+ * hweightN - returns the hamming weight of a N-bit word
+ * @x: the word to weigh
+ *
+ * The Hamming Weight of a number is the total number of bits set in it.
+ */
+
+unsigned int hweight32(unsigned int w)
+{
+ unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
+ res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
+ res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F);
+ res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF);
+ return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
+}
+EXPORT_SYMBOL(hweight32);
+
+unsigned int hweight16(unsigned int w)
+{
+ unsigned int res = (w & 0x5555) + ((w >> 1) & 0x5555);
+ res = (res & 0x3333) + ((res >> 2) & 0x3333);
+ res = (res & 0x0F0F) + ((res >> 4) & 0x0F0F);
+ return (res & 0x00FF) + ((res >> 8) & 0x00FF);
+}
+EXPORT_SYMBOL(hweight16);
+
+unsigned int hweight8(unsigned int w)
+{
+ unsigned int res = (w & 0x55) + ((w >> 1) & 0x55);
+ res = (res & 0x33) + ((res >> 2) & 0x33);
+ return (res & 0x0F) + ((res >> 4) & 0x0F);
+}
+EXPORT_SYMBOL(hweight8);
+
+unsigned long hweight64(__u64 w)
+{
+#if BITS_PER_LONG == 32
+ return hweight32((unsigned int)(w >> 32)) + hweight32((unsigned int)w);
+#elif BITS_PER_LONG == 64
+ u64 res;
+ res = (w & 0x5555555555555555ul) + ((w >> 1) & 0x5555555555555555ul);
+ res = (res & 0x3333333333333333ul) + ((res >> 2) & 0x3333333333333333ul);
+ res = (res & 0x0F0F0F0F0F0F0F0Ful) + ((res >> 4) & 0x0F0F0F0F0F0F0F0Ful);
+ res = (res & 0x00FF00FF00FF00FFul) + ((res >> 8) & 0x00FF00FF00FF00FFul);
+ res = (res & 0x0000FFFF0000FFFFul) + ((res >> 16) & 0x0000FFFF0000FFFFul);
+ return (res & 0x00000000FFFFFFFFul) + ((res >> 32) & 0x00000000FFFFFFFFul);
+#else
+#error BITS_PER_LONG not defined
+#endif
+}
+EXPORT_SYMBOL(hweight64);
--
^ permalink raw reply [flat|nested] 5+ messages in thread* [patch 32/47] powerpc: use generic bitops
[not found] <20060214050351.252615000@localhost.localdomain>
` (3 preceding siblings ...)
2006-02-14 5:04 ` [patch 15/47] generic hweight{64,32,16,8}() Akinobu Mita
@ 2006-02-14 5:04 ` Akinobu Mita
4 siblings, 0 replies; 5+ messages in thread
From: Akinobu Mita @ 2006-02-14 5:04 UTC (permalink / raw)
To: linux-kernel; +Cc: akpm, linuxppc-dev, Akinobu Mita
- remove __{,test_and_}{set,clear,change}_bit() and test_bit()
- remove generic_fls64()
- remove generic_hweight{64,32,16,8}()
- remove sched_find_first_bit()
Signed-off-by: Akinobu Mita <mita@miraclelinux.com>
arch/powerpc/Kconfig | 4 +
include/asm-powerpc/bitops.h | 105 +------------------------------------------
2 files changed, 8 insertions(+), 101 deletions(-)
Index: 2.6-rc/include/asm-powerpc/bitops.h
===================================================================
--- 2.6-rc.orig/include/asm-powerpc/bitops.h
+++ 2.6-rc/include/asm-powerpc/bitops.h
@@ -184,72 +184,7 @@ static __inline__ void set_bits(unsigned
: "cc");
}
-/* Non-atomic versions */
-static __inline__ int test_bit(unsigned long nr,
- __const__ volatile unsigned long *addr)
-{
- return 1UL & (addr[BITOP_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
-}
-
-static __inline__ void __set_bit(unsigned long nr,
- volatile unsigned long *addr)
-{
- unsigned long mask = BITOP_MASK(nr);
- unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
-
- *p |= mask;
-}
-
-static __inline__ void __clear_bit(unsigned long nr,
- volatile unsigned long *addr)
-{
- unsigned long mask = BITOP_MASK(nr);
- unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
-
- *p &= ~mask;
-}
-
-static __inline__ void __change_bit(unsigned long nr,
- volatile unsigned long *addr)
-{
- unsigned long mask = BITOP_MASK(nr);
- unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
-
- *p ^= mask;
-}
-
-static __inline__ int __test_and_set_bit(unsigned long nr,
- volatile unsigned long *addr)
-{
- unsigned long mask = BITOP_MASK(nr);
- unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
- unsigned long old = *p;
-
- *p = old | mask;
- return (old & mask) != 0;
-}
-
-static __inline__ int __test_and_clear_bit(unsigned long nr,
- volatile unsigned long *addr)
-{
- unsigned long mask = BITOP_MASK(nr);
- unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
- unsigned long old = *p;
-
- *p = old & ~mask;
- return (old & mask) != 0;
-}
-
-static __inline__ int __test_and_change_bit(unsigned long nr,
- volatile unsigned long *addr)
-{
- unsigned long mask = BITOP_MASK(nr);
- unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
- unsigned long old = *p;
-
- *p = old ^ mask;
- return (old & mask) != 0;
-}
+#include <asm-generic/bitops/non-atomic.h>
/*
* Return the zero-based bit position (LE, not IBM bit numbering) of
@@ -310,16 +245,9 @@ static __inline__ int fls(unsigned int x
asm ("cntlzw %0,%1" : "=r" (lz) : "r" (x));
return 32 - lz;
}
-#define fls64(x) generic_fls64(x)
+#include <asm-generic/bitops/fls64.h>
-/*
- * hweightN: returns the hamming weight (i.e. the number
- * of bits set) of a N-bit word
- */
-#define hweight64(x) generic_hweight64(x)
-#define hweight32(x) generic_hweight32(x)
-#define hweight16(x) generic_hweight16(x)
-#define hweight8(x) generic_hweight8(x)
+#include <asm-generic/bitops/hweight.h>
#define find_first_zero_bit(addr, size) find_next_zero_bit((addr), (size), 0)
unsigned long find_next_zero_bit(const unsigned long *addr,
@@ -397,32 +325,7 @@ unsigned long find_next_zero_le_bit(cons
#define minix_find_first_zero_bit(addr,size) \
find_first_zero_le_bit((unsigned long *)addr, size)
-/*
- * Every architecture must define this function. It's the fastest
- * way of searching a 140-bit bitmap where the first 100 bits are
- * unlikely to be set. It's guaranteed that at least one of the 140
- * bits is cleared.
- */
-static inline int sched_find_first_bit(const unsigned long *b)
-{
-#ifdef CONFIG_PPC64
- if (unlikely(b[0]))
- return __ffs(b[0]);
- if (unlikely(b[1]))
- return __ffs(b[1]) + 64;
- return __ffs(b[2]) + 128;
-#else
- if (unlikely(b[0]))
- return __ffs(b[0]);
- if (unlikely(b[1]))
- return __ffs(b[1]) + 32;
- if (unlikely(b[2]))
- return __ffs(b[2]) + 64;
- if (b[3])
- return __ffs(b[3]) + 96;
- return __ffs(b[4]) + 128;
-#endif
-}
+#include <asm-generic/bitops/sched.h>
#endif /* __KERNEL__ */
Index: 2.6-rc/arch/powerpc/Kconfig
===================================================================
--- 2.6-rc.orig/arch/powerpc/Kconfig
+++ 2.6-rc/arch/powerpc/Kconfig
@@ -37,6 +37,10 @@ config RWSEM_XCHGADD_ALGORITHM
bool
default y
+config GENERIC_HWEIGHT
+ bool
+ default y
+
config GENERIC_CALIBRATE_DELAY
bool
default y
--
^ permalink raw reply [flat|nested] 5+ messages in thread