文件系统中查找,空闲inode时候需要用到
一个每个文件系统都有自己的实现(如minix),现在kernel中统一调用这个:
static inline unsigned long find_first_zero_bit_le(const void *addr, unsigned long size) { return find_first_zero_bit(addr, size); }
找到最近的一个还有有效bit的字:
unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size) { const unsigned long *p = addr; unsigned long result = 0; unsigned long tmp; while (size & ~(BITS_PER_LONG-1)) { if (~(tmp = *(p++))) goto found; result += BITS_PER_LONG; size -= BITS_PER_LONG; } if (!size) return result; tmp = (*p) | (~0UL << size); if (tmp == ~0UL) /* Are any bits zero? */ return result + size; /* Nope. */ found: return result + ffz(tmp); }
在一个字里面找有效bit的位置,这个方法kernel中有很多实现,其中大部分是
直接用汇编实现的(当然也大部分看不懂),其中有个c语言实现很有意思(一个字里面还用上了二分差查找)
/** * __ffs - find first bit in word. * @word: The word to search * * Undefined if no bit exists, so code should check against 0 first. */ static __always_inline unsigned long __ffs(unsigned long word) { int num = 0; #if BITS_PER_LONG == 64 if ((word & 0xffffffff) == 0) { num += 32; word >>= 32; } #endif if ((word & 0xffff) == 0) { num += 16; word >>= 16; } if ((word & 0xff) == 0) { num += 8; word >>= 8; } if ((word & 0xf) == 0) { num += 4; word >>= 4; } if ((word & 0x3) == 0) { num += 2; word >>= 2; } if ((word & 0x1) == 0) num += 1; return num; }