在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的应用
转载自:http://blog.chinaunix.net/u/28535/showart_1164637.html
阅读(1920) | 评论(0) | 转发(0) |