unsigned long data[0];
} bitmap_t;
-#define BITMAP_SIZE(nbits) (((nbits/BITS_PER_LONG)+1)*sizeof(long)+sizeof(bitmap_t))
+#define CFS_BITMAP_SIZE(nbits) \
+ (((nbits/BITS_PER_LONG)+1)*sizeof(long)+sizeof(bitmap_t))
static inline
bitmap_t *ALLOCATE_BITMAP(int size)
{
bitmap_t *ptr;
- OBD_ALLOC(ptr, BITMAP_SIZE(size));
+ OBD_ALLOC(ptr, CFS_BITMAP_SIZE(size));
if (ptr == NULL)
RETURN(ptr);
ptr->size = size;
- memset(ptr->data, 0, BITMAP_SIZE(size));
RETURN (ptr);
}
-#define FREE_BITMAP(ptr) OBD_FREE(ptr, BITMAP_SIZE(ptr->size))
+#define FREE_BITMAP(ptr) OBD_FREE(ptr, CFS_BITMAP_SIZE(ptr->size))
static inline
void bitmap_set(bitmap_t *bitmap, int nbit)
static inline
int bitmap_check(bitmap_t *bitmap, int nbit)
{
- int pos = nbit % BITS_PER_LONG;
- return test_bit(pos, bitmap->data+(nbit/BITS_PER_LONG));
+ return test_bit(nbit, bitmap->data);
}
/* return 0 is bitmap has none set bits */
#ifndef __LIBCFS_USER_BITOPS_H__
#define __LIBCFS_USER_BITOPS_H__
-unsigned long find_next_bit(const unsigned int *addr,
- unsigned long size, unsigned long offset);
+/* test if bit nr is set in bitmap addr; returns previous value of bit nr */
+static __inline__ int set_bit(int nr, long * addr)
+{
+ long mask;
-unsigned long find_next_zero_bit(const unsigned int *addr,
- unsigned long size, unsigned long offset);
+ addr += nr / BITS_PER_LONG;
+ mask = 1UL << (nr & (BITS_PER_LONG - 1));
+ nr = (mask & *addr) != 0;
+ *addr |= mask;
+ return nr;
+}
+
+/* clear bit nr in bitmap addr; returns previous value of bit nr*/
+static __inline__ int clear_bit(int nr, long * addr)
+{
+ long mask;
+
+ addr += nr / BITS_PER_LONG;
+ mask = 1UL << (nr & (BITS_PER_LONG - 1));
+ nr = (mask & *addr) != 0;
+ *addr &= ~mask;
+ return nr;
+}
+
+static __inline__ int test_bit(int nr, long * addr)
+{
+ return ((1UL << (nr & (BITS_PER_LONG - 1))) & ((addr)[nr / BITS_PER_LONG])) != 0;
+}
+
+/* using binary seach */
+static __inline__ unsigned long __ffs(long data)
+{
+ int pos = 0;
+
+#if BITS_PER_LONG == 64
+ if ((data & 0xFFFFFFFF) == 0) {
+ pos += 32;
+ data >>= 32;
+ }
+#endif
+ if ((data & 0xFFFF) == 0) {
+ pos += 16;
+ data >>= 16;
+ }
+ if ((data & 0xFF) == 0) {
+ pos += 8;
+ data >>= 8;
+ }
+ if ((data & 0xF) == 0) {
+ pos += 4;
+ data >>= 4;
+ }
+ if ((data & 0x3) == 0) {
+ pos += 2;
+ data >>= 2;
+ }
+ if ((data & 0x1) == 0)
+ pos += 1;
+
+ return pos;
+}
+
+#define __ffz(x) __ffs(~(x))
+
+unsigned long find_next_bit(unsigned long *addr,
+ unsigned long size, unsigned long offset);
+
+unsigned long find_next_zero_bit(unsigned long *addr,
+ unsigned long size, unsigned long offset);
#define find_first_bit(addr,size) (find_next_bit((addr),(size),0))
#define find_first_zero_bit(addr,size) (find_next_zero_bit((addr),(size),0))
#include <libcfs/libcfs.h>
#include <libcfs/kp30.h>
+#include <libcfs/user-bitops.h>
-#include <string.h> /* for ffs - confirm POSIX */
+#define OFF_BY_START(start) ((start)/BITS_PER_LONG)
-#define BITS_PER_WORD 32
-#define OFF_BY_START(start) ((start)/BITS_PER_WORD)
-
-unsigned long find_next_bit(const unsigned int *addr,
- unsigned long size, unsigned long offset)
+unsigned long find_next_bit(unsigned long *addr,
+ unsigned long size, unsigned long offset)
{
- uint32_t *word, *last;
- unsigned int first_bit, bit, base;
+ unsigned long *word, *last;
+ unsigned long first_bit, bit, base;
word = addr + OFF_BY_START(offset);
last = addr + OFF_BY_START(size-1);
- first_bit = offset % BITS_PER_WORD;
+ first_bit = offset % BITS_PER_LONG;
base = offset - first_bit;
if (offset >= size)
return size;
if (first_bit != 0) {
int tmp = (*word++) & (~0UL << first_bit);
- bit = ffs(tmp);
- if (bit < BITS_PER_WORD)
+ bit = __ffs(tmp);
+ if (bit < BITS_PER_LONG)
goto found;
word++;
- base += BITS_PER_WORD;
+ base += BITS_PER_LONG;
}
while (word <= last) {
- if (*word != 0ul) {
- bit = ffs(*word);
+ if (*word != 0UL) {
+ bit = __ffs(*word);
goto found;
}
word++;
- base += BITS_PER_WORD;
+ base += BITS_PER_LONG;
}
return size;
found:
return base + bit;
}
-unsigned long find_next_zero_bit(const unsigned int *addr,
- unsigned long size, unsigned long offset)
+unsigned long find_next_zero_bit(unsigned long *addr,
+ unsigned long size, unsigned long offset)
{
- uint32_t *word, *last;
- unsigned int first_bit, bit, base;
+ unsigned long *word, *last;
+ unsigned long first_bit, bit, base;
word = addr + OFF_BY_START(offset);
last = addr + OFF_BY_START(size-1);
- first_bit = offset % BITS_PER_WORD;
+ first_bit = offset % BITS_PER_LONG;
base = offset - first_bit;
if (offset >= size)
return size;
if (first_bit != 0) {
int tmp = (*word++) & (~0UL << first_bit);
- bit = ffs(~tmp);
- if (bit < BITS_PER_WORD)
+ bit = __ffz(tmp);
+ if (bit < BITS_PER_LONG)
goto found;
word++;
- base += BITS_PER_WORD;
+ base += BITS_PER_LONG;
}
while (word <= last) {
- if (*word != ~0ul) {
- bit = ffs(*word);
+ if (*word != ~0UL) {
+ bit = __ffz(*word);
goto found;
}
word++;
- base += BITS_PER_WORD;
+ base += BITS_PER_LONG;
}
return size;
found:
cfs_free(addr);
}
-/*
- * This uses user-visible declarations from <linux/kdev_t.h>
- */
-#ifdef __linux__
-#include <linux/kdev_t.h>
-#endif
-
void cfs_enter_debugger(void)
{
/*