Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tools lib: Sync tools/lib/find_bit.c with the kernel

Need to move the bitmap.[ch] things from tools/perf/ to tools/lib, will
be done in the next patches.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: David Ahern <dsahern@gmail.com>
Cc: George Spelvin <linux@horizon.com
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Cc: Wang Nan <wangnan0@huawei.com>
Cc: Yury Norov <yury.norov@gmail.com>
Link: http://lkml.kernel.org/n/tip-5fys65wkd7gu8j7a7xgukc5t@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

+51 -54
+49 -54
tools/lib/find_bit.c
··· 1 - /* find_next_bit.c: fallback find next bit implementation 1 + /* bit search implementation 2 2 * 3 - * Copied from lib/find_next_bit.c to tools/lib/find_bit.c 3 + * Copied from lib/find_bit.c to tools/lib/find_bit.c 4 4 * 5 5 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. 6 6 * Written by David Howells (dhowells@redhat.com) 7 + * 8 + * Copyright (C) 2008 IBM Corporation 9 + * 'find_last_bit' is written by Rusty Russell <rusty@rustcorp.com.au> 10 + * (Inspired by David Howell's find_next_bit implementation) 11 + * 12 + * Rewritten by Yury Norov <yury.norov@gmail.com> to decrease 13 + * size and improve performance, 2015. 7 14 * 8 15 * This program is free software; you can redistribute it and/or 9 16 * modify it under the terms of the GNU General Public License ··· 19 12 */ 20 13 21 14 #include <linux/bitops.h> 22 - #include <asm/types.h> 23 - #include <asm/byteorder.h> 15 + #include <linux/bitmap.h> 16 + #include <linux/kernel.h> 24 17 25 - #define BITOP_WORD(nr) ((nr) / BITS_PER_LONG) 18 + #if !defined(find_next_bit) 19 + 20 + /* 21 + * This is a common helper function for find_next_bit and 22 + * find_next_zero_bit. The difference is the "invert" argument, which 23 + * is XORed with each fetched word before searching it for one bits. 24 + */ 25 + static unsigned long _find_next_bit(const unsigned long *addr, 26 + unsigned long nbits, unsigned long start, unsigned long invert) 27 + { 28 + unsigned long tmp; 29 + 30 + if (!nbits || start >= nbits) 31 + return nbits; 32 + 33 + tmp = addr[start / BITS_PER_LONG] ^ invert; 34 + 35 + /* Handle 1st word. */ 36 + tmp &= BITMAP_FIRST_WORD_MASK(start); 37 + start = round_down(start, BITS_PER_LONG); 38 + 39 + while (!tmp) { 40 + start += BITS_PER_LONG; 41 + if (start >= nbits) 42 + return nbits; 43 + 44 + tmp = addr[start / BITS_PER_LONG] ^ invert; 45 + } 46 + 47 + return min(start + __ffs(tmp), nbits); 48 + } 49 + #endif 26 50 27 51 #ifndef find_next_bit 28 52 /* ··· 62 24 unsigned long find_next_bit(const unsigned long *addr, unsigned long size, 63 25 unsigned long offset) 64 26 { 65 - const unsigned long *p = addr + BITOP_WORD(offset); 66 - unsigned long result = offset & ~(BITS_PER_LONG-1); 67 - unsigned long tmp; 68 - 69 - if (offset >= size) 70 - return size; 71 - size -= result; 72 - offset %= BITS_PER_LONG; 73 - if (offset) { 74 - tmp = *(p++); 75 - tmp &= (~0UL << offset); 76 - if (size < BITS_PER_LONG) 77 - goto found_first; 78 - if (tmp) 79 - goto found_middle; 80 - size -= BITS_PER_LONG; 81 - result += BITS_PER_LONG; 82 - } 83 - while (size & ~(BITS_PER_LONG-1)) { 84 - if ((tmp = *(p++))) 85 - goto found_middle; 86 - result += BITS_PER_LONG; 87 - size -= BITS_PER_LONG; 88 - } 89 - if (!size) 90 - return result; 91 - tmp = *p; 92 - 93 - found_first: 94 - tmp &= (~0UL >> (BITS_PER_LONG - size)); 95 - if (tmp == 0UL) /* Are any bits set? */ 96 - return result + size; /* Nope. */ 97 - found_middle: 98 - return result + __ffs(tmp); 27 + return _find_next_bit(addr, size, offset, 0UL); 99 28 } 100 29 #endif 101 30 ··· 72 67 */ 73 68 unsigned long find_first_bit(const unsigned long *addr, unsigned long size) 74 69 { 75 - const unsigned long *p = addr; 76 - unsigned long result = 0; 77 - unsigned long tmp; 70 + unsigned long idx; 78 71 79 - while (size & ~(BITS_PER_LONG-1)) { 80 - if ((tmp = *(p++))) 81 - goto found; 82 - result += BITS_PER_LONG; 83 - size -= BITS_PER_LONG; 72 + for (idx = 0; idx * BITS_PER_LONG < size; idx++) { 73 + if (addr[idx]) 74 + return min(idx * BITS_PER_LONG + __ffs(addr[idx]), size); 84 75 } 85 - if (!size) 86 - return result; 87 76 88 - tmp = (*p) & (~0UL >> (BITS_PER_LONG - size)); 89 - if (tmp == 0UL) /* Are any bits set? */ 90 - return result + size; /* Nope. */ 91 - found: 92 - return result + __ffs(tmp); 77 + return size; 93 78 } 94 79 #endif
+2
tools/perf/util/include/linux/bitmap.h
··· 11 11 void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1, 12 12 const unsigned long *bitmap2, int bits); 13 13 14 + #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1))) 15 + 14 16 #define BITMAP_LAST_WORD_MASK(nbits) \ 15 17 ( \ 16 18 ((nbits) % BITS_PER_LONG) ? \