理解bitops中的__set_bit及其应用
在include/linux/bitops.h中对比特位操作的API中: bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
如何来理解下面的代码呢?
// Note: nr为要设置的比特位(可以是0或者更大的值),addr为位图的起始地址
void __set_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = 1 << (nr & 0x1f);
unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
*p |= mask;
}
由于0x1f(16进制) = 0001 1111(二进制) = 31(十进制),
因而将上述代码翻译为下面的代码,则更为清晰一些:
void __set_bit(int nr, volatile unsigned long *addr)
{
addr[nr >> 5] |= (1UL << (nr & 31));
}
而且nr>>5 即nr/32,那么下面的代码就更加清晰了:
addr[nr/32] |= (1UL << (nr & (32-1)));
addr是一个类型为unsigned long(32 bits)的数组,通过nr/32得到要设置的比特位nr位于该数组中的哪一个unsigned long。
然后,通过(nr & (32-1))得到该unsigned long整数中是哪一位(第0位、第1位、...还是第31位?)需要设置。
最后,通过addr[nr/32] |= (1UL << (nr & (32-1)))设置该unsigned long整数中相应的比特位。
理解了上述代码,则其它比特位操作API就容易懂了。
比特位操作在代码中到处使用,灵活使用这些操作将能够大大提高系统的性能,例如:
1. Linux 2.6中进程调度中bitops的应用
Linux 2.6内核重写了进程调度这部分,其时间复杂度为O(1)
每个cpu有自己单独的运行队列runqueues,而每个运行队列中,把进程分为活动进程队列和过期进程队列。
struct prio_array {
unsigned int nr_active; //当前队列进程数
DECLARE_BITMAP(bitmap, MAX_PRIO+1);//位图,每一位表示对应级别的进程链表是否有进程
struct list_head queue[MAX_PRIO]; //进程链表,共MAX_PRIO(140)级,进程按其优先级存放在这个链表中
};
每次调度时,从活动进程队列的最高优先级链表中选择第一个进程作为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的应用
struct input_dev {
void *private;
const char *name;
const char *phys;
const char *uniq;
struct input_id id;
/*
* 根据各种输入信号的类型来建立类型为unsigned long 的数组,
* 数组的每1bit代表一种信号类型,
* 内核中会对其进行置位或清位操作来表示事件的发生和被处理.
*/
unsigned long evbit[NBITS(EV_MAX)];
unsigned long keybit[NBITS(KEY_MAX)];
unsigned long relbit[NBITS(REL_MAX)];
unsigned long absbit[NBITS(ABS_MAX)];
unsigned long mscbit[NBITS(MSC_MAX)];
unsigned long ledbit[NBITS(LED_MAX)];
unsigned long sndbit[NBITS(SND_MAX)];
unsigned long ffbit[NBITS(FF_MAX)];
unsigned long swbit[NBITS(SW_MAX)];
.........................................
};
3. Port中bitops的应用
4. VLAN(1-4094)中bitops的应用
更多推荐
所有评论(0)