DECLARE_BITMAP宏
位图简介
- 位图:用每一个bit来表示一个含义。比如你需要标记32个资源的占用情况,可以用一个int型变量(刚好32bit)来标记,bit位为0代表资源空闲,bit为1表示资源被占用,你通过位运算检查每个bit的值就知道对应资源的占用情况。
DECLARE_BITMAP定义
在内核中我们经常看到位图结构,我们先来看看其定义:
#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) //向上取整
#define BITS_PER_BYTE 8
#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
#define DECLARE_BITMAP(name,bits) \
unsigned long name[BITS_TO_LONGS(bits)]
- 宏的定义是用来定义一个位图变量,本质就是一个unsigned long类型的数组。比如你要标记38个资源,但是一个unsigned long类型变量只有32bit(32位系统中),所以就要定义2个unsigned long类型变量(总共有64bit),但是实际只用到38bit;在64位系统中long类型就有64位,所以表示38个资源也是绰绰有余的,超过64个资源就需要两个long类型的变量了,以此类推。
- 宏的参数:name是变量名,bits是位图有多少个位,就是需要多少个bit;
宏展开
如上图定义,我们一层层展开:
#define MAX_GENERATION_NUMBER 127
#define BITS_PER_BYTE 8
DECLARE_BITMAP(bit_string, MAX_GENERATION_NUMBER + 1);
unsigned long bit_string[BITS_TO_LONGS(128)]
unsigned long bit_string[DIV_ROUND_UP(128, 8 * 4)] (这里按照32位来计算)
unsigned long bit_string[DIV_ROUND_UP(128, 32)]
unsigned long bit_string[(((128) + (32) - 1) / (32))]
unsigned long bit_string[4]
- 这里以32位系统来计算,32位系统中sizeof(long)就是32位
- 从上面我们可以看到,DECLARE_BITMAP(bit_string,MAX_GENERATION_NUMBER + 1)最终展开成了unsigned long bit_string[4]这个数组,4个unsigned long就可以代表128位了。如果是129个资源,那么计算下来就需要5个unsigned long来表示了(160位),但其实只用了129位。