linux位操作
来源:互联网 发布:内江恒迈网络 编辑:程序博客网 时间:2024/06/09 19:23
include/asm-generic/bitops/atomic.h
- void set_bit(int nr, volatile unsigned long *addr)
- void clear_bit(int nr, volatile unsigned long *addr)
- void change_bit(int nr, volatile unsigned long *addr)
- int test_and_set_bit(int nr, volatile unsigned long *addr)
- int test_and_clear_bit(int nr, volatile unsigned long *addr)
上面的这些方法都是原子操作的。
void set_bit(int nr, volatile unsigned long *addr)
将存放在addr内存地址的unsigned long类型的数据的nr位设成1。这儿改变的是addr地址的数据的相应位,而这个数据的类型为unsigend long。参数nr是可以大于unsigend long的bit的位数(一般为0~31)。假设传入的nr为33,那么修改的就是addr+1地址的数据的第1位(从第0位开始计算)。
void clear_bit(int nr, volatile unsigned long *addr)
将相应位设成0。
void change_bit(int nr, volatile unsigned long *addr)
将相应位置反。
int test_and_set_bit(int nr, volatile unsigned long *addr)
将相应位设成1,并返回未设置之前的值。如果之前的值为0,返回0,如果之前的值为1,返回真(非0,可能是1,也可能是-1,跟平台有关)。
int test_and_clear_bit(int nr, volatile unsigned long *addr)
将相应位设成0,并返回未设置之前的值。
Linux还提供了一些非原子操作的方法:
- void __set_bit(int nr, volatile unsigned long *addr)
- void __clear_bit(int nr, volatile unsigned long *addr)
- void __change_bit(int nr, volatile unsigned long *addr)
- int __test_and_set_bit(int nr, volatile unsigned long *addr)
- int __test_and_clear_bit(int nr, volatile unsigned long *addr)
- int __test_and_change_bit(int nr,volatile unsigned long *addr)
- int test_bit(int nr, const volatile unsigned long *addr)
int test_bit(int nr, const volatile unsigned long *addr)
检测相应位的值,如果相应位为0,则返回假;如果相应位为1,则返回真。
除了上面一些操作外,经常还会遇到一些与位相关的宏:
include/linux/bitops.h- #define BIT(nr)(1UL << (nr))
- #define BIT_MASK(nr)(1UL << ((nr) % BITS_PER_LONG))
- #define BIT_WORD(nr)((nr) / BITS_PER_LONG)
- #define BITS_PER_BYTE8
- #define BITS_PER_LONG (sizeof(long) * BITS_PER_BYTE)
- #define BITS_TO_LONGS(nr)DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
- #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
BIT(nr)与BIT_MASK(nr)的效果一样,都是将nr位置1。不同的是当nr大于等于long型所占用的位数时,BIT(nr)返回0。例如,一个long占32位,那么BIT(32)=0,BIT_MASK(32)=1。
BIT_WORD(nr)
BITS_TO_LONGS(nr)
上面两个宏都表示:一个数占用nr位,那么这个数就需要BITS_TO_LONGS(nr)个long型数据来表示。比如,long型数据占用32位。BITS_TO_LONGS(0)=0,BITS_TO_LONGS(1~32)=1。
DIV_ROUND_UP(n,d)
返回n/d的最小整数。
还有下面几个:
fls(unsigned count);
当count为0时,fls(0)返回0。
当count>0时,fls(count)返回将count转换成二进制后,从高位到低位第一个为1的位数(从0开始计算)+1。
比如,fls(1)=1,fls(2) = 2 ,fls(3)=2 ,fls(4)=3, fls(5)=3。
get_count_order(unsigned count);
返回log2count。如果log2count不是整数,那么返回大的整数。
如:当count为1时,返回0,当count为2时,返回1,当count为3~4时,返回2,当count为5~8时,返回3。
判断一个数count是否为2的指数的方法:
count&(count-1)
如果count是2的指数,那么上面与运算结果为0,否则不为0。内核中使用下面方法。
- bool is_power_of_2(unsigned long n)
- {
- return (n != 0 && ((n & (n - 1)) == 0));
- }
- unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size)
在以addr开始的内存区中查找第一个值为0的位,查找范围为size大小。
addr为内存区的起始地址,size为要查找的最大长度。
返回第一个位为0的位号。如果没找到,则返回值大于size。
在内存当中从addr为起始地址,以size为最大的搜索范围寻找第一个是0的bit位,并且返回该bit位的bit位号(从0开始计算)。该方法用于取得一个long型数据的最低0位。
如:unsigned long data = 0x5f,则find_first_zero_bit(&data,sizeof(data)) = 5。
- linux位操作
- linux原子/位操作
- linux位操作API
- linux 位操作c语言
- Linux系统内核驱动之位操作
- 位操作
- 位操作
- 位操作
- 位操作
- 位操作
- 位操作
- 位操作
- 位操作
- 位操作
- 位操作
- 位操作
- 位操作
- 位操作
- java自学视频整理
- shell十三问总结
- maven nexus私服配置
- Shell 基本运算符
- Android中FTP服务器搭建入门
- linux位操作
- A计划
- webservice笔记
- Mybatis中resultMap
- php 使用会话注销用户
- Sql Server exists 查询相同姓名或编号 年份最大的一条数据
- GENERATE AN OPENSSL CERTIFICATE REQUEST WITH SHA256 SIGNATURE
- CreateMutex函数
- 可行 虚拟机 centos 配置网络