summaryrefslogtreecommitdiff
path: root/ext2fs/bitmap.c
diff options
context:
space:
mode:
authorMiles Bader <miles@gnu.org>1995-04-15 01:38:03 +0000
committerMiles Bader <miles@gnu.org>1995-04-15 01:38:03 +0000
commit6552368cf39ba0001cb5347f3b82d9c5c6690d1e (patch)
treef619ce1de56d0bef0e74791c7f54facf2ad3f644 /ext2fs/bitmap.c
parent7a4d05cd773e2c0a0f5972699b9e33b838f52a70 (diff)
Formerly bitmap.c.~4~
Diffstat (limited to 'ext2fs/bitmap.c')
-rw-r--r--ext2fs/bitmap.c104
1 files changed, 102 insertions, 2 deletions
diff --git a/ext2fs/bitmap.c b/ext2fs/bitmap.c
index b46c6dca..296c839b 100644
--- a/ext2fs/bitmap.c
+++ b/ext2fs/bitmap.c
@@ -1,5 +1,5 @@
/*
- * linux/fs/ext2/bitmap.c
+ * linux/fs/ext2/bitmap.c (etc
*
* Copyright (C) 1992, 1993, 1994, 1995
* Remy Card (card@masi.ibp.fr)
@@ -9,7 +9,7 @@
static int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0};
-unsigned long ext2_count_free (char * map, unsigned int numchars)
+unsigned long count_free (char * map, unsigned int numchars)
{
unsigned int i;
unsigned long sum = 0;
@@ -21,3 +21,103 @@ unsigned long ext2_count_free (char * map, unsigned int numchars)
nibblemap[(map[i] >> 4) & 0xf];
return (sum);
}
+
+/* ---------------------------------------------------------------- */
+
+static int ffz_nibble_map[] = {0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0};
+
+inline unsigned long ffz(unsigned long word)
+{
+ int offset = 0;
+ if ((word & 0xFFFF) == 0xFFFF)
+ {
+ word >>= 16;
+ offset += 16;
+ }
+ if ((word & 0xFF) == 0xFF)
+ {
+ word >>= 8;
+ offset += 8;
+ }
+ if ((word & 0xF) == 0xF)
+ {
+ word >>= 4;
+ offset += 4;
+ }
+ return ffz_nibble_map[word] + offset;
+}
+
+/* ---------------------------------------------------------------- */
+
+/*
+ * Copyright 1994, David S. Miller (davem@caip.rutgers.edu).
+ */
+
+/* find_next_zero_bit() finds the first zero bit in a bit string of length
+ * 'size' bits, starting the search at bit 'offset'. This is largely based
+ * on Linus's ALPHA routines, which are pretty portable BTW.
+ */
+
+extern inline unsigned long
+find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
+{
+ unsigned long *p = ((unsigned long *) addr) + (offset >> 6);
+ unsigned long result = offset & ~31UL;
+ unsigned long tmp;
+
+ if (offset >= size)
+ return size;
+ size -= result;
+ offset &= 31UL;
+ if (offset)
+ {
+ tmp = *(p++);
+ tmp |= ~0UL >> (32-offset);
+ if (size < 32)
+ goto found_first;
+ if (~tmp)
+ goto found_middle;
+ size -= 32;
+ result += 32;
+ }
+ while (size & ~32UL)
+ {
+ if (~(tmp = *(p++)))
+ goto found_middle;
+ result += 32;
+ size -= 32;
+ }
+ if (!size)
+ return result;
+ tmp = *p;
+
+found_first:
+ tmp |= ~0UL << size;
+found_middle:
+ return result + ffz(tmp);
+}
+
+/* Linus sez that gcc can optimize the following correctly, we'll see if this
+ * holds on the Sparc as it does for the ALPHA.
+ */
+
+inline int
+find_first_zero_bit(void *buf, unsigned len)
+{
+ return find_next_zero_bit(buf, len, 0);
+}
+
+/* ---------------------------------------------------------------- */
+
+/* Returns a pointer to the first occurence of CH in the buffer BUF of len
+ LEN, or BUF + LEN if CH doesn't occur. */
+void *memscan(void *buf, unsigned char ch, unsigned len)
+{
+ unsigned char *p = (unsigned char *)buf;
+ while (len-- > 0)
+ if (*p == ch)
+ break;
+ else
+ p++;
+ return (void *)p;
+}