find_next_bit.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. /* find_next_bit.c: fallback find next bit implementation
  2. *
  3. * Copied from lib/find_next_bit.c to tools/lib/next_bit.c
  4. *
  5. * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
  6. * Written by David Howells (dhowells@redhat.com)
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version
  11. * 2 of the License, or (at your option) any later version.
  12. */
  13. #include <linux/bitops.h>
  14. #include <asm/types.h>
  15. #include <asm/byteorder.h>
  16. #define BITOP_WORD(nr) ((nr) / BITS_PER_LONG)
  17. #ifndef find_next_bit
  18. /*
  19. * Find the next set bit in a memory region.
  20. */
  21. unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
  22. unsigned long offset)
  23. {
  24. const unsigned long *p = addr + BITOP_WORD(offset);
  25. unsigned long result = offset & ~(BITS_PER_LONG-1);
  26. unsigned long tmp;
  27. if (offset >= size)
  28. return size;
  29. size -= result;
  30. offset %= BITS_PER_LONG;
  31. if (offset) {
  32. tmp = *(p++);
  33. tmp &= (~0UL << offset);
  34. if (size < BITS_PER_LONG)
  35. goto found_first;
  36. if (tmp)
  37. goto found_middle;
  38. size -= BITS_PER_LONG;
  39. result += BITS_PER_LONG;
  40. }
  41. while (size & ~(BITS_PER_LONG-1)) {
  42. if ((tmp = *(p++)))
  43. goto found_middle;
  44. result += BITS_PER_LONG;
  45. size -= BITS_PER_LONG;
  46. }
  47. if (!size)
  48. return result;
  49. tmp = *p;
  50. found_first:
  51. tmp &= (~0UL >> (BITS_PER_LONG - size));
  52. if (tmp == 0UL) /* Are any bits set? */
  53. return result + size; /* Nope. */
  54. found_middle:
  55. return result + __ffs(tmp);
  56. }
  57. #endif
  58. #ifndef find_first_bit
  59. /*
  60. * Find the first set bit in a memory region.
  61. */
  62. unsigned long find_first_bit(const unsigned long *addr, unsigned long size)
  63. {
  64. const unsigned long *p = addr;
  65. unsigned long result = 0;
  66. unsigned long tmp;
  67. while (size & ~(BITS_PER_LONG-1)) {
  68. if ((tmp = *(p++)))
  69. goto found;
  70. result += BITS_PER_LONG;
  71. size -= BITS_PER_LONG;
  72. }
  73. if (!size)
  74. return result;
  75. tmp = (*p) & (~0UL >> (BITS_PER_LONG - size));
  76. if (tmp == 0UL) /* Are any bits set? */
  77. return result + size; /* Nope. */
  78. found:
  79. return result + __ffs(tmp);
  80. }
  81. #endif