在编写应用层代码中使用位图,发现内核中已经有现成的实现便使用之。对位图的使用主要是几个

关键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的使用的更多相关文章

  1. [翻译] Linux 内核中的位数组和位操作

    目录 Linux 内核里的数据结构 原文链接与说明 Linux 内核中的位数组和位操作 位数组声明 体系结构特定的位操作 通用位操作 链接 Linux 内核里的数据结构 原文链接与说明 https:/ ...

  2. 内核中dump_stack的实现原理(3) —— 内核函数printk的实现

      参考内核文档: Documentation/printk-formats.txt   在内核中使用dump_stack的时候可以看到如下用法: static inline void print_i ...

  3. Linux 2.6内核中新的锁机制--RCU

    转自:http://www.ibm.com/developerworks/cn/linux/l-rcu/ 一. 引言 众所周知,为了保护共享数据,需要一些同步机制,如自旋锁(spinlock),读写锁 ...

  4. Linux 内核中的 Device Mapper 机制

    本文结合具体代码对 Linux 内核中的 device mapper 映射机制进行了介绍.Device mapper 是 Linux 2.6 内核中提供的一种从逻辑设备到物理设备的映射框架机制,在该机 ...

  5. Unix内核中打开文件的表示

    Unix内核中已经打开文件,通过三种数据结构表示: 每个进程的进程表中的记录项,包含打开的文件的文件描述符表,与之关联的是: 文件描述符标识 指向一个文件表项的指针 内核为所有打开文件维持一张文件表, ...

  6. 内核中用于数据接收的结构体struct msghdr(转)

    内核中用于数据接收的结构体struct msghdr(转) 我们从一个实际的数据包发送的例子入手,来看看其发送的具体流程,以及过程中涉及到的相关数据结构.在我们的虚拟机上发送icmp回显请求包,pin ...

  7. 向linux内核中添加外部中断驱动模块

    本文主要介绍外部中断驱动模块的编写,包括:1.linux模块的框架及混杂设备的注册.卸载.操作函数集.2.中断的申请及释放.3.等待队列的使用.4.工作队列的使用.5.定时器的使用.6.向linux内 ...

  8. linux 驱动学习笔记02--应用实例:在内核中新增驱动代码目录和子目录

    下面来看一个综合实例,假设我们要在内核源代码 drivers 目录下为 ARM 体系结构新增如下用于 test driver 的树型目录:| --test  | -- cpu  | -- cpu.c ...

  9. [php-src]窥探Php内核中的变量

    内容均以php-5.6.14为例. 在看各种组合数据类型之前,有必要先熟悉下 Zend/zend_types.h 里面的自定义数据类型. #ifndef ZEND_TYPES_H // 防止多次 in ...

随机推荐

  1. PEP8特性

    Python 的代码风格由 PEP 8 描述.这个文档描述了 Python 编程风格的方方面面.在遵守这个文档的条件下,不同程序员编写的 Python 代码可以保持最大程度的相似风格.这样就易于阅读, ...

  2. 插件 原生js 省市区 三级联动 源码

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. wxpython demo

    #!/usr/bin/python # encoding: utf-8 '''Spare.py is a starting point for a wxPython program.''' impor ...

  4. python每日一类(1):pathlib

    每天学习一个python的类(大多数都是第三方的),聚沙成金. -------------------------------------------------------------------- ...

  5. Android 之 AlarmManager(定时器) 的介绍和使用

    AlarmManager 包含的主要方法: // 取消已经注册的与参数匹配的定时器 void cancel(PendingIntent operation) //注册一个新的延迟定时器void set ...

  6. Jquery学习之路(二) 实现table样式的设定

    上一篇jquery实现checkbox的全选,得到了一些朋友的建议,其中插件的定义我的确不太清楚,也闹了个笑话,有些朋友建议我去看<锋利的Jquery>,说实话正在看了.由于正在学习中,我 ...

  7. sql 事物 锁 快照(转发的,写的非常好)

    隔离级别定义事务处理数据读取操作的隔离程度,在SQL Server中,隔离级别只会影响读操作申请的共享锁(Shared Lock),而不会影响写操作申请的互斥锁(Exclusive Lock),隔离级 ...

  8. CF987A Infinity Gauntlet【STL】

    [链接]:CF987A [分析]:运用map [代码]: #include <iostream> #include<queue> #include<string.h> ...

  9. l洛谷——P1211 [USACO1.3]牛式 Prime Cryptarithm

    P1211 [USACO1.3]牛式 Prime Cryptarithm 题目描述 下面是一个乘法竖式,如果用我们给定的那n个数字来取代*,可以使式子成立的话,我们就叫这个式子牛式. *** x ** ...

  10. Linux漏洞建议工具Linux Exploit Suggester

     Linux漏洞建议工具Linux Exploit Suggester 在Linux系统渗透测试中,通常使用Nessus.OpenVAS对目标主机进行扫描,获取目标主机可能存在的漏洞.如果无法进行漏洞 ...