Find_next_zero_bit:
IntFind_next_zero_bit
(Const unsigned long * ADDR, int size, int offset)
In * ADDR query, starting from the offset, the first number of digits not 0 (the first digit starts from 0)
, Note: The minimum offset value is 0, and the maximum value is sizeof (unsigned long) * 8-1
// Why * 8 ??
Sample:
For example, you can find the first number of digits not 0 after the first 5th bits of Bitmap (32 bits in total) (the query result is 5)
--
5
4 3 2 1 0
| --- |
|0
| 1 | 1 | 1 | 1 | 1 |
| --- |
Bitmap = 31 = 011111
---------------------------------------------------------------
# Include // needed by all modules
# Include // needed for kern_alert
Int init_module (void)
{
Int devnum;
Unsigned long bitmap = 31;
Devnum = find_next_zero_bit (& bitmap, 32, 5 );
Printk ("<1> devnum = % d/N", devnum );
Return 0;
}
Void cleanup_module (void)
{
Printk (kern_alert "Goodbye./N ");
}
# Define declare_bitmap (name, BITs )/
Unsigned long name [bits_to_longs (BITs)]
Http://blog.chinaunix.net/u1/38994/showart_2002937.html
Function prototype analysis:
Unsigned long find_next_zero_bit (const unsigned long * ADDR, unsigned
Long size,
Unsigned long offset)
{
Const unsigned
Long * P = ADDR + bitop_word (offset); // offset is in the 32-bit long address pointed to by P.
Unsigned long result = offset &~ (BITS_PER_LONG-1 );//
Offset is the fourth byte of result.
Unsigned long TMP;
If (Offset> =
Size)
Return size;
Size-=
Result; // adjust the 32-bit integer
Offset
% = Bits_per_long; // Number of the 32-bit offset
If (offset ){//
Offset is not in The 0th bits of a long data, and in the 1-31 bits [Luther. gliethttp]
TMP = * (p ++ );
TMP | = ~ 0ul> (bits_per_long-offset );//
Fill 0-offset data with 1.
If (size <
Bits_per_long) // less than 32 bits
Goto
Found_first;
If (~ TMP)
// If the value is not 0, the value 0 is included.
Goto found_middle;
Size-=
Bits_per_long ;//
If the above ~ If TMP is equal to 0, the * P data is 32-bit. 1. [Luther. gliethttp]
Result + =
Bits_per_long;
}
While (size &~ (BITS_PER_LONG-1 ))
{// Well, execute here. Our offset is already in the 4-byte 0th bits.
If
(~ (TMP = * (p ++ )))//
4-byte quick query. If ~ TMP is not 0, indicating that the 32-bit data contains 0 data. Find. [Luther. gliethttp]
Goto found_middle;
Result + =
Bits_per_long; // to the next 4-byte Space
Size-=
Bits_per_long; // reduce 4 bytes of data
}
If
(! Size )//
Size is equal to 0, indicating that size is equal to an integer multiple of 4 bytes, and all data has been queried,
Return
Result ;//
All data is 1 and no 0 digits are found. result is equal to size. [Luther. gliethttp]
TMP =
* P ;//
The size is not an integer multiple of 32 bits, and several BITs are not checked. Continue with the following check. [Luther. gliethtp]
Found_first:
TMP | = ~ 0ul <size ;//
0-size indicates valid data and size-31 indicates unused space. Therefore, set size-31 to full 1.
If (TMP = ~ 0ul)
/* Are any bits zero? * /// If TMP is all 1, it means no one is found.
Return
Result + size;/* nope .*///
Result + size is equal to the size of the parameter passed in by the function. [Luther. gliethttp]
Found_middle:
Return result + ffz (TMP );//
We found in the 32-bit DATA 0-31 that there must be a 0-bit value. Calculate the number of its digits. [Luther. gliethttp]
}
# Define
Ffz (x) _ FFs (~ (X ))//
_ FFS: locate the offset value with 1 value for the first time, and locate [Luther. gliethttp] From bit0 to bit31.
/**
* _ FFS
-Find first bit in word.
* @ Word: the word to search
*
*
Undefined if no bit exists, so code shoshould check against 0 first.
*/
Static
Inline unsigned long _ FFs (unsigned long word)
{
Int num = 0;
# If
Bits_per_long = 64
If (word & 0 xffffffff) = 0 ){
Num + = 32;
Word >>=32;
}
# Endif
If (word & 0 xFFFF) = 0 ){//
If the low 16 BITs do not have a value of 1, then num plus 16 and the high 16 bits move to the low 16 bits
Num + =
16 ;//
In this case, the low 16 bits always remove the inevitable data that does not exist.
Word >>=16;
}
If (word & 0xff) = 0) {// low 8-bit?
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 ;//
In this case, num is the offset value of 1. [Luther. gliethttp]
}