标签:style io color ar 使用 sp strong 文件 div
位操作在kernel中很普遍,以下针对__set_bit函数为例来分析其原理:
在kernel/include/asm-generic/bitops/non-atomic.h头文件下有如下
在kernel/include/linux/bitops.h中有BIT_MASK,BIT_WORD
点击(此处)折叠或打开
在kernel/arch/arm/include/asm/types.h中有BITS_PER_LONG
点击(此处)折叠或打开
所以__set_bit函数内容等价表示如下:
点击(此处)折叠或打开
addr是一个类型为unsigned long(32 bits)的数组,通过nr/32得到要设置的比特位nr位于该数组中的哪一个unsigned long。
然后,通过( nr%32 )得到该unsigned long整数中是哪一位(第0位、第1位、...还是第31位?)需要设置。
最后,通过 addr[nr/32] |= (1UL << (nr % 32)) 设置该unsigned long整数中相应的比特位。
addr地址所指的32bit位图如下:
________________
0 <--- |_|_|_|_|_|_|_|_|...._|
1 <--- |____________...._|
2 <--- |____________...._|
. <--- |____________...._|
. <--- |____________...._|
nr/32 <--- |____________...._|
理解了上述代码,则其它比特位操作API就容易懂了。
__clear_bit: 将addr所指的地址处的值第nr位清0,方法一般 addr[nr/32] & 11111011111
__change_bit: 将addr所指的地址处的值第nr位取反,方法一般 addr[nr/32] ^ 00000100000
__test_and_set_bit:将addr所指的地址处的值第nr位置1,返回该bit原始值(0或1);
__test_and_clear_bit:将addr所指的地址处的值第nr位清0,返回该bit原始值(0或1);
__test_and_change_bit:将addr所指的地址处的值第nr位取反,返回该bit原始值(0或1);
test_bit:即测试nr位是否被置位,置位返回1;
——————————————————————————————————————————————
比特位操作在代码中到处使用,灵活使用这些操作将能够大大提高系统的性能,以下举例说明:
1. Linux 2.6中进程调度中bitops的应用
Linux 2.6内核重写了进程调度这部分,其时间复杂度为O(1)
每个cpu有自己单独的运行队列runqueues,而每个运行队列中,把进程分为活动进程队列和过期进程队列。
每次调度时,从活动进程队列的最高优先级链表中选择第一个进程作为next。
我们来看看它是如何选择的。
我们先看prio_arry中的queue[MAX_PRIO], 进程按优先级放入这个队列中,queue[0]中的全部进程其优先级为0,其优先级最高,queue[1]中的全部进程其优先级为1, 优先级的值越小优先运行。
0~MAX_RT_PRIO(100)为实时进程的优先级,MAX_RT_PRIO~MAX_PRIO(140)为普通进程的优先级。
bitmap为5个32位整数,它的前140位对应140个优先级,比如:bitmap的第5位置1,表示优先级为5的进程队列存在进程。
idx = sched_find_first_bit(array->bitmap)就是查找bitmap中第一个为1的位,那么就可以获取当前优先级最高的进程队列。
2. Linux中输入子系统中bitops的应用
点击(此处)折叠或打开
3. Port中bitops的应用
4. VLAN(1-4094)中bitops的应用
【转】【Linux】理解bitops中的__set_bit及其应用
标签:style io color ar 使用 sp strong 文件 div
原文地址:http://www.cnblogs.com/ftsummerer/p/4079491.html