内核中bitmap的使用
在编写应用层代码中使用位图,发现内核中已经有现成的实现便使用之。对位图的使用主要是几个
关键API。
第一:bitmap_zero函数用于初始化位图
源码如下:
/*
*@dst: 位图的起始地址
*@nbits: 位图的个数
*/
static inline void bitmap_zero(unsigned long *dst, int nbits)
{
int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
memset(dst, , len);
}
第二:bitmap_set函数用于设置特定的位
/*
* @map: 位图的内存空间的首地址
* @start:需要设置的起始位
* @nr : 需要设置的位的数目
*/
void bitmap_set(unsigned long *map, int start, int nr)
{
unsigned long *p = map + BIT_WORD(start); //以unsigned long 为单位的情况,设置起始位置
const int size = start + nr; //需要设置的末位,不包括此位
/*
* @bits_to_set 在一个需要设置的unsigned long中,可能需要设置的位
* [0_____start_________BITS_PER_LONG)
* [0____________________bits_to_set)
*/
int bits_to_set = BITS_PER_LONG - (start % BITS_PER_LONG);
unsigned long mask_to_set = BITMAP_FIRST_WORD_MASK(start); while (nr - bits_to_set >= ) {
*p |= mask_to_set;
nr -= bits_to_set;
bits_to_set = BITS_PER_LONG; //经过上一步的操作后,需要设置的位都是BITS_PER_LONG的倍数
mask_to_set = ~0UL;
p++;
}
if (nr) { //nr 必须大于1,此函数才有效果
mask_to_set &= BITMAP_LAST_WORD_MASK(size);
*p |= mask_to_set; //产生最终的效果
}
}
与bit_set函数相对应的是bit_clear函数用于清除位,其实现原理和bit_set函数类似。
第三:find_first_zero_bit函数用于找到第一个清空位
/*
* Find the first cleared bit in a memory region.
* @addr: 位图的起始位置
* @size: 位图的大小
*/
unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size)
{
const unsigned long *p = addr;
unsigned long result = ;
unsigned long tmp; while (size & ~(BITS_PER_LONG-)) { //位图的大小超过一个 BIT_PER_LONG的情况下
if (~(tmp = *(p++)))
goto found;
result += BITS_PER_LONG;
size -= BITS_PER_LONG;
}
if (!size) //此情况成立的时候,也是没有找到。且size应该是 BIT_PER_LONG的整数倍。
return result; tmp = (*p) | (~0UL << size);
if (tmp == ~0UL) /* Are any bits zero? */
return result + size; /* Nope. */ //如果没有找到就会返回 size
found:
return result + ffz(tmp);
}
于此函数对应的是函数find_first_bit寻找第一个设置位。
第四:find_next_zero_bit 和 find_next_bit 函数可以在第一次找到后,再次寻找清空位或设置位。
具体使用情况可以参考:
备注:
位图除了应用于内存管理,还可以应用到对共享资源的管理,LDD3的P128就有提到。
内核中bitmap的使用的更多相关文章
- [翻译] Linux 内核中的位数组和位操作
目录 Linux 内核里的数据结构 原文链接与说明 Linux 内核中的位数组和位操作 位数组声明 体系结构特定的位操作 通用位操作 链接 Linux 内核里的数据结构 原文链接与说明 https:/ ...
- 内核中dump_stack的实现原理(3) —— 内核函数printk的实现
参考内核文档: Documentation/printk-formats.txt 在内核中使用dump_stack的时候可以看到如下用法: static inline void print_i ...
- Linux 2.6内核中新的锁机制--RCU
转自:http://www.ibm.com/developerworks/cn/linux/l-rcu/ 一. 引言 众所周知,为了保护共享数据,需要一些同步机制,如自旋锁(spinlock),读写锁 ...
- Linux 内核中的 Device Mapper 机制
本文结合具体代码对 Linux 内核中的 device mapper 映射机制进行了介绍.Device mapper 是 Linux 2.6 内核中提供的一种从逻辑设备到物理设备的映射框架机制,在该机 ...
- Unix内核中打开文件的表示
Unix内核中已经打开文件,通过三种数据结构表示: 每个进程的进程表中的记录项,包含打开的文件的文件描述符表,与之关联的是: 文件描述符标识 指向一个文件表项的指针 内核为所有打开文件维持一张文件表, ...
- 内核中用于数据接收的结构体struct msghdr(转)
内核中用于数据接收的结构体struct msghdr(转) 我们从一个实际的数据包发送的例子入手,来看看其发送的具体流程,以及过程中涉及到的相关数据结构.在我们的虚拟机上发送icmp回显请求包,pin ...
- 向linux内核中添加外部中断驱动模块
本文主要介绍外部中断驱动模块的编写,包括:1.linux模块的框架及混杂设备的注册.卸载.操作函数集.2.中断的申请及释放.3.等待队列的使用.4.工作队列的使用.5.定时器的使用.6.向linux内 ...
- linux 驱动学习笔记02--应用实例:在内核中新增驱动代码目录和子目录
下面来看一个综合实例,假设我们要在内核源代码 drivers 目录下为 ARM 体系结构新增如下用于 test driver 的树型目录:| --test | -- cpu | -- cpu.c ...
- [php-src]窥探Php内核中的变量
内容均以php-5.6.14为例. 在看各种组合数据类型之前,有必要先熟悉下 Zend/zend_types.h 里面的自定义数据类型. #ifndef ZEND_TYPES_H // 防止多次 in ...
随机推荐
- [03] html 中引入与使用css
1. 使用style属性 <a style="color: red;"> hello ,there use style attribute</a> 2. l ...
- js剪贴板操作
这是一个很有意思的地方,很多不了解的人或者初级的js编程者会觉得很不可思议,js都那么强大了,访问剪贴板一个粘贴复制,大概就是一行命令的事情,但是事实如此,js对于访问本地计算机的剪贴板的支持其实是十 ...
- (十)Linux查看系统信息的一些命令及查看已安装软件包的命令
转自:http://cheneyph.iteye.com/blog/824746 系统 # uname -a # 查看内核/操作系统/CPU信息 # head -n 1 /etc/issue # 查看 ...
- 简述web工程师的职责与学习
最近两年web突然很火,也有很多人涌入这一行,但这行实际上是进来的人很多,出去的人也很多. 在我眼里,Web前端开发工程师的职责有:1.Web前端表现层及与前后端交互的架构设计和开发2.配合后台开发人 ...
- 学习hibernate,这个系列很不错
从这里入,感谢作者啊. 看了很多资料,这个是最能让我入门的.感觉. http://blog.csdn.net/yerenyuan_pku/article/details/52745486
- [BZOJ2084][Poi2010]Antisymmetry 二分+hash
2084: [Poi2010]Antisymmetry Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 812 Solved: 503[Submit] ...
- 在 iSCSI Target 服务器中使用LVM创建和设置LUN(二)
LUN是逻辑单元号,它与iSCSI存储服务器共享.iSCSI 目标器通过TCP/IP网络共享它的物理驱动器给发起程序(initiator).这些来自一个大型存储(SAN:Storage Area Ne ...
- haproxy代理kibana、nginx代理kibana并实现登录验证
在使用ELK进行日志统计的时候,由于Kibana自身并没有身份验证的功能,任何人只要知道链接地址就可以正常登录到Kibana控制界面,由于日常的查询,添加和删除日志都是在同一个web中进行,这样就有极 ...
- 集合框架(04)HashMap
集合Map的简单方法:该集合存储键值对,一对一对往里面存,而且要保证健的唯一性 1.添加 put(K key,V value) putAll(Map<? Extends k, ? extends ...
- JSP(待更新)
1.概念: 所谓JSP就是在HTML中嵌入大量的java代码而已.