Skip to content
Snippets Groups Projects
Select Git revision
  • d59288b75797fd982546aee7ba24a495dee128dd
  • openEuler-1.0-LTS default protected
  • openEuler-22.09
  • OLK-5.10
  • openEuler-22.03-LTS
  • openEuler-22.03-LTS-Ascend
  • master
  • openEuler-22.03-LTS-LoongArch-NW
  • openEuler-22.09-HCK
  • openEuler-20.03-LTS-SP3
  • openEuler-21.09
  • openEuler-21.03
  • openEuler-20.09
  • 4.19.90-2210.5.0
  • 5.10.0-123.0.0
  • 5.10.0-60.63.0
  • 5.10.0-60.62.0
  • 4.19.90-2210.4.0
  • 5.10.0-121.0.0
  • 5.10.0-60.61.0
  • 4.19.90-2210.3.0
  • 5.10.0-60.60.0
  • 5.10.0-120.0.0
  • 5.10.0-60.59.0
  • 5.10.0-119.0.0
  • 4.19.90-2210.2.0
  • 4.19.90-2210.1.0
  • 5.10.0-118.0.0
  • 5.10.0-106.19.0
  • 5.10.0-60.58.0
  • 4.19.90-2209.6.0
  • 5.10.0-106.18.0
  • 5.10.0-106.17.0
33 results

find_bit.c

Blame
  • find_bit.c 2.66 KiB
    #include <linux/bitops.h>
    
    /**
     * find_next_bit - find the next set bit in a memory region
     * @addr: The address to base the search on
     * @offset: The bitnumber to start searching at
     * @size: The maximum size to search
     */
    unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
    				unsigned long offset)
    {
    	const unsigned long *p = addr + (offset >> 6);
    	unsigned long result = offset & ~63UL;
    	unsigned long tmp;
    
    	if (offset >= size)
    		return size;
    	size -= result;
    	offset &= 63UL;
    	if (offset) {
    		tmp = *(p++);
    		tmp &= (~0UL << offset);
    		if (size < 64)
    			goto found_first;
    		if (tmp)
    			goto found_middle;
    		size -= 64;
    		result += 64;
    	}
    	while (size & ~63UL) {
    		if ((tmp = *(p++)))
    			goto found_middle;
    		result += 64;
    		size -= 64;
    	}
    	if (!size)
    		return result;
    	tmp = *p;
    
    found_first:
    	tmp &= (~0UL >> (64 - size));
    	if (tmp == 0UL)        /* Are any bits set? */
    		return result + size; /* Nope. */
    found_middle:
    	return result + __ffs(tmp);
    }
    
    /* 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.
     */
    
    unsigned long find_next_zero_bit(const unsigned long *addr,
    			unsigned long size, unsigned long offset)
    {
    	const unsigned long *p = addr + (offset >> 6);
    	unsigned long result = offset & ~63UL;
    	unsigned long tmp;
    
    	if (offset >= size)
    		return size;
    	size -= result;
    	offset &= 63UL;
    	if (offset) {
    		tmp = *(p++);
    		tmp |= ~0UL >> (64-offset);
    		if (size < 64)
    			goto found_first;
    		if (~tmp)
    			goto found_middle;
    		size -= 64;
    		result += 64;
    	}
    	while (size & ~63UL) {
    		if (~(tmp = *(p++)))
    			goto found_middle;
    		result += 64;
    		size -= 64;
    	}
    	if (!size)
    		return result;
    	tmp = *p;
    
    found_first:
    	tmp |= ~0UL << size;
    	if (tmp == ~0UL)        /* Are any bits zero? */
    		return result + size; /* Nope. */
    found_middle:
    	return result + ffz(tmp);
    }
    
    unsigned long find_next_zero_le_bit(unsigned long *addr, unsigned long size, unsigned long offset)
    {
    	unsigned long *p = addr + (offset >> 6);
    	unsigned long result = offset & ~63UL;
    	unsigned long tmp;
    
    	if (offset >= size)
    		return size;
    	size -= result;
    	offset &= 63UL;
    	if(offset) {
    		tmp = __swab64p(p++);
    		tmp |= (~0UL >> (64-offset));
    		if(size < 64)
    			goto found_first;
    		if(~tmp)
    			goto found_middle;
    		size -= 64;
    		result += 64;
    	}
    	while(size & ~63) {
    		if(~(tmp = __swab64p(p++)))
    			goto found_middle;
    		result += 64;
    		size -= 64;
    	}
    	if(!size)
    		return result;
    	tmp = __swab64p(p);
    found_first:
    	tmp |= (~0UL << size);
    	if (tmp == ~0UL)        /* Are any bits zero? */
    		return result + size; /* Nope. */
    found_middle:
    	return result + ffz(tmp);
    }