内核中的位图介绍(DECLARE_BITMAP宏)

Posted 正在起飞的蜗牛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内核中的位图介绍(DECLARE_BITMAP宏)相关的知识,希望对你有一定的参考价值。

1、DECLARE_BITMAP宏定义

#define	DIV_ROUND_UP(x,y)	(((x) + ((y) - 1)) / (y))	//向上取整

#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)]

(1)位图:用每一个bit来表示一个含义。比如你需要标记32个资源的占用情况,可以用一个int型变量(刚好32bit)来标记,bit位为0代表资源空闲,bit为1表示资源被占用,你通过位运算检查每个bit的值就知道对应资源的占用情况。
(2)宏的定义是用来定义一个位图变量,本质就是一个unsigned long类型的数组。比如你要标记38个资源,但是一个unsigned long类型变量只有32bit,所以就要定义2个unsigned long类型变量(总共有64bit),但是实际只用到38bit;
(3)宏的参数:name是变量名,bits是位图有多少个位,就是需要多少个bit;

2、宏展开分析

#宏定义
#define DYNAMIC_MINORS 64 
DECLARE_BITMAP(misc_minors, DYNAMIC_MINORS);

#宏展开分析
unsigned long misc_minors[BITS_TO_LONGS(64)]
	unsigned long misc_minors[BITS_TO_LONGS(64)]
		unsigned long misc_minors[DIV_ROUND_UP(64, 8 * sizeof(long))]
			unsigned long misc_minors[(((64) + ((32) - 1)) / (32))]
				unsigned long misc_minors[2]
#宏展开最终
unsigned long misc_minors[2];

(1)定义了unsigned long类型的数组,数组名是misc_minors,有2个成员变量;
(2)DECLARE_BITMAP宏会向上取整。这里位图大小是64,两个unsigned long变量刚好是64bit,如果位图大小是65,则数组会定义3个unsigned long类型成员,3个unsigned long类型变量总共96bit,但是实际只用到65bit。

3、find_first_zero_bit宏 和 set_bit宏

#ifndef __ARMEB__

//小端
#define set_bit(nr,p)			ATOMIC_BITOP_LE(set_bit,nr,p)
#define find_first_zero_bit(p,sz)	_find_first_zero_bit_le(p,sz)

#else

//大端
#define set_bit(nr,p)			ATOMIC_BITOP_BE(set_bit,nr,p)
#define find_first_zero_bit(p,sz)	_find_first_zero_bit_be(p,sz)

#endif

(1)find_first_zero_bit宏:返回位图中第一个值为0的bit的下标,也就是没有被占用的;
(2)set_bit宏:将位图中的某个位置为1,表示被占用;
(3)具体应用:参考博客《misc驱动框架》;

以上是关于内核中的位图介绍(DECLARE_BITMAP宏)的主要内容,如果未能解决你的问题,请参考以下文章

Linux内核__setup()宏介绍

内核中的alternative宏

内核中的alternative宏

rt-thread的位图调度算法分析

Linux内核模块简介

Linux内核中双向链表的经典实现