内核中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 ...
随机推荐
- 创建型设计模式之单例模式(Singleton)
结构 意图 保证一个类仅有一个实例,并提供一个访问它的全局访问点. 适用性 当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时. 当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更 ...
- Linux下Redis使用
1. 简介 REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统. 2. 安装 安装方法如下: # yum i ...
- UVA 10205 Stack 'em Up
直接模拟就好. #include <map> #include <set> #include <list> #include <cmath> #incl ...
- Centos 环境变量
1. 控制台中,不赞成使用这种方法,因为换个shell,你的设置就无效了,因此这种方法仅仅是临时使用,以后要使用的时候又要重新设置,比较麻烦. 这个只针对特定的shell; $ PATH=" ...
- python 操作数据库1--连接、执行sql语句
#!/usr/bin/env python # -*- coding:utf-8 -*- # @Time : 2017/11/20 16:03 # @Author : lijunjiang # @Fi ...
- Python学习杂记_15_正则表达式
正则表达式 正则表达式就是用来查找字符串的,它能够查找规则比较复杂的字符串.使用正则表达式首先要导入re模块import re s = "besttest is good!besttest ...
- 【linux高级程序设计】(第十三章)Linux Socket网络编程基础 4
网络调试工具 tcpdump 功能:打印指定网络接口中与布尔表达式匹配的报头信息 关键字: ①类型:host(默认).net.port host 210.27.48.2 //指明是一台主机 net 2 ...
- Mysql优化的方法
一.表的优化: 1: 定长与变长分离 如 time.手机号等,每一单元值占的字节是固定的. 核心且常用字段,宜建成定长,放在一张表,查询速度会很快 而varchar, text,blob,这种变长字段 ...
- Flask的上下文管理机制
前引 在了解flask上下文管理机制之前,先来一波必知必会的知识点. 面向对象双下方法 首先,先来聊一聊面向对象中的一些特殊的双下划线方法,比如__call__.__getattr__系列.__get ...
- 51nod 1087 1 10 100 1000【打表】
题目来源: Ural 1209 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题 收藏 关注 1,10,100,1000...组成序列1101001000...,求 ...