在linux内核中有很多位运算函数,如:set_bit,clear_bit,clear_bit,test_and_set_bit等等。
1. set_bit
- <span style="font-size:16px;">static __always_inline void
- set_bit(unsigned int nr, volatile unsigned long *addr)
- </span>
在起始地址为addr的位图中设置第nr位;是原子操作。
2. __set_bit
- <span style="font-size:16px;">static __always_inline void
- set_bit(unsigned int nr, volatile unsigned long *addr)
- </span>
在起始地址为addr的位图中设置第nr位;非原子操作。
3. clear_bit
- <span style="font-size:16px;">static __always_inline void
- clear_bit(int nr, volatile unsigned long *addr)
- </span>
清除起始地址为addr的位图中的第nr位,改操作是原子操作但不具有加锁功能,若要用于加锁目的,应当调用smp_mb__before_clear_bit 或smp_mb__after_clear_bit函数,以确保任何改变在其他的处理器上是可见的。
4. change_bit
- <span style="font-size:16px;">static inline void change_bit(int nr, volatile unsigned long *addr)
- </span>
在起始地址为addr的位图中改变第nr位;
5. test_and_set_bit
- <span style="font-size:16px;">static inline int test_and_set_bit(int nr, volatile unsigned long *addr)
- </span>
在起始地址为addr的位图中设置第nr位;并返回原来的值,原子操作。
6. test_and_clear_bit
- <span style="font-size:16px;">static inline int test_and_clear_bit(int nr, volatile unsigned long *addr)
- </span>
在起始地址为addr的位图中清除第nr位;并返回原来的值,原子操作。
7. test_and_change_bit
- <span style="font-size:16px;">static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
- </span>
在起始地址为addr的位图中更改第nr位;并返回原来的值,原子操作。
8. test_bit
- <span style="font-size:16px;">#define test_bit(nr, addr) \
- (__builtin_constant_p((nr)) \
- ? constant_test_bit((nr), (addr)) \
- : variable_test_bit((nr), (addr)))
- </span>
根据nr是否为编译时常数来调用不同的函数,
若编译时为常数,则调用constant_test_bit
- <span style="font-size:16px;">static __always_inline int constant_test_bit(unsigned int nr, const volatile unsigned long *addr)
- </span>
若编译时为非常数,则调用variable_test_bit
- <span style="font-size:16px;">static inline int variable_test_bit(int nr, volatile const unsigned long *addr)</span>
9. find_first_zero_bit
- <pre class="cpp" name="code"><span style="font-size:16px;">int find_first_zero_bit (void * addr, unsigned size) </span></pre>
- <pre></pre>
- <p><span style="font-family:Microsoft YaHei"><span style="font-size:16px"><span style="font-family:Microsoft YaHei"> </span>addr为内存区的起始地址,size为要查找的最大长度,返回第一个位为0的位号</span></span></p>
- <p><span style="font-family:Microsoft YaHei"><span style="font-size:16px"><strong>10. find_next_zero_bit</strong> <span style="font-family:Microsoft YaHei"></span></span></span></p>
- <span style="font-family:Microsoft YaHei"></span><pre class="cpp" name="code"><span style="font-size:16px;">int find_next_zero_bit (void * addr, int size, int offset) </span></pre>
- <p><span style="font-size:16px"><span style="font-family:Microsoft YaHei"> </span>addr为内存区的起始地址,size为要查找的最大长度,offset开始搜索的起始位号。</span></p>
- <p><span style="font-family:Microsoft YaHei"><span style="font-size:16px"><strong>11. ffz <br>
- </strong><span style="font-family:Microsoft YaHei"> </span>ffz (x):在字x中搜索第一个0。</span></span></p>
- <p><span style="font-family:Microsoft YaHei"><span style="font-size:16px"><strong>12. ffs <br>
- </strong><span style="font-family:Microsoft YaHei"> </span>ffs (x):<span style="font-family:Microsoft YaHei"> </span>在字x中搜索第一个已设置的位。</span></span></p>
- <p><span style="font-family:Microsoft YaHei"><span style="font-size:16px"><strong>13. hweight32</strong> <br>
- <span style="font-family:Microsoft YaHei"> </span>返回一个N位字的加权平衡值 <br>
- <strong>14. hweight32 ( x)</strong><br>
- <span style="font-family:Microsoft YaHei"> </span>x为要加权的字 ,一个数的加权平衡是这个数所有位的总和。</span></span></p>