diff options
author | Miles Bader <miles@gnu.org> | 1995-04-15 01:38:03 +0000 |
---|---|---|
committer | Miles Bader <miles@gnu.org> | 1995-04-15 01:38:03 +0000 |
commit | 6552368cf39ba0001cb5347f3b82d9c5c6690d1e (patch) | |
tree | f619ce1de56d0bef0e74791c7f54facf2ad3f644 /ext2fs | |
parent | 7a4d05cd773e2c0a0f5972699b9e33b838f52a70 (diff) |
Formerly bitmap.c.~4~
Diffstat (limited to 'ext2fs')
-rw-r--r-- | ext2fs/bitmap.c | 104 |
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; +} |