diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2008-12-03 11:16:59 +1100 |
---|---|---|
committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2008-12-03 11:16:59 +1100 |
commit | b032dfc80921daa9c957810fb2e2ff253aaf2ac4 (patch) | |
tree | dea437cca9fc39cfdaffd1da99ef24d355ac6818 /lib | |
parent | cf3ff7af2e0be88651723bfbc52afc026b201aef (diff) |
bitmap:find_last_bit
Impact: New API
As the name suggests. For the moment everyone uses the generic one.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Kconfig | 4 | ||||
-rw-r--r-- | lib/Makefile | 1 | ||||
-rw-r--r-- | lib/find_next_bit.c | 31 |
3 files changed, 36 insertions, 0 deletions
diff --git a/lib/Kconfig b/lib/Kconfig index 85cf7ea978aa..bfc7b8f33388 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -13,6 +13,10 @@ config GENERIC_FIND_FIRST_BIT config GENERIC_FIND_NEXT_BIT bool +config GENERIC_FIND_LAST_BIT + bool + default y + config CRC_CCITT tristate "CRC-CCITT functions" help diff --git a/lib/Makefile b/lib/Makefile index 7cb65d85aeb0..cc8335a921e7 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -37,6 +37,7 @@ lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o lib-$(CONFIG_GENERIC_FIND_FIRST_BIT) += find_next_bit.o lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find_next_bit.o +lib-$(CONFIG_GENERIC_FIND_LAST_BIT) += find_next_bit.o obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o obj-$(CONFIG_PLIST) += plist.o diff --git a/lib/find_next_bit.c b/lib/find_next_bit.c index 24c59ded47a0..0fc495273924 100644 --- a/lib/find_next_bit.c +++ b/lib/find_next_bit.c @@ -159,6 +159,37 @@ found: EXPORT_SYMBOL(find_first_zero_bit); #endif /* CONFIG_GENERIC_FIND_FIRST_BIT */ +#ifdef CONFIG_GENERIC_FIND_LAST_BIT +unsigned long find_last_bit(const unsigned long *addr, unsigned long size) +{ + unsigned long words; + unsigned long tmp; + + /* Start at final word. */ + words = size / BITS_PER_LONG; + + /* Partial final word? */ + if (size & (BITS_PER_LONG-1)) { + tmp = (addr[words] & (~0UL >> (BITS_PER_LONG + - (size & (BITS_PER_LONG-1))))); + if (tmp) + goto found; + } + + while (words) { + tmp = addr[--words]; + if (tmp) { +found: + return words * BITS_PER_LONG + __fls(tmp); + } + } + + /* Not found */ + return size; +} +EXPORT_SYMBOL(find_last_bit); +#endif /* CONFIG_GENERIC_FIND_LAST_BIT */ + #ifdef __BIG_ENDIAN /* include/linux/byteorder does not support "unsigned long" type */ |