-------------------------------------------
本文系作者原创, 欢迎大家转载!
转载请注明出处:netwalker.blog.chinaunix.net
-------------------------------------------
通过位图提供的两种状态可以在非常节约内存的情况下表示开关变量,并且同类这类变量可以紧凑而高效的统一进行处理。有很多内核子系统都需要位图的支持,但是不同的情况又需要不同的位图个数,比如SMP系统上的CPU位图cpumask的位数位NR_CPUS,而内存管理区的位图数为MAX_ZONES_PER_ZONELIST。但是所有的位图都要转换为基本的数据类型,比如int,short等,Linux将定义位图的功能集中到一个名为DECLARE_BITMAP的宏。
 include/linux/types.h
#define DECLARE_BITMAP(name,bits) \
unsigned long name[BITS_TO_LONGS(bits)]

这里可以看到DECLARE_BITMAP的作用是尝试定义一个类型为unsigned long,名字为name的数组。而数组的维度由位图中的位数通过BITS_TO_LONGS计算而得。

 include/linux/bitops.h
#define BITS_PER_BYTE 8
#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))

BITS_TO_LONGS通过DIV_ROUND_UP宏完成。DIV_ROUND_UP根据nr参数计算至少需要几个long型才能满足当前位图的需求。不知道为什么Linux不使用char型,这样不是更节约内存吗?显然DECLARE_BITMAP的引入的根本目的并不是用来节约内存,而是方便对长位图的操作,而通常8位位图的定义并不通过它来定义,而是直接定义位掩码,比如对文件权限的定义。

内核定义了一系列的宏和函数来对DECLARE_BITMAP定义的位图进行操作,它们分别位于bitmap.h和bitmap.c中。这些宏和函数的操作思想是一致的。

 /arch/arm/include/asm/types.h
#define BITS_PER_LONG 32 include/linux/bitmap.h
static inline void bitmap_zero(unsigned long *dst, int nbits)
{
if (nbits <= BITS_PER_LONG)
*dst = 0UL;
else {
int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
memset(dst, , len);
}
}

尽管在特定体系的代码中BITS_PER_LONG被定义为32以增加运算速度,但是它更应该通过sizeof(long) * BITS_PER_BYTE来定义。bitmap_zero用来清空所有的位图。分析它发现,它首先判断是否超过一个long型,如果没有那么直接对它赋值0UL即可。否则就要通过memset对整个数组进行操作。其他函数亦同。一些常用的位图操作函数如下所示:

  • bitmap_zero 清所有比特位为0,被用来初始化位图。圆整到unsigned long。
  • bitmap_fill 置nbits指定个数的比特位为1。精确到位。
  • bitmap_copy 从src复制所有比特位到dst。圆整到unsigned long。
  • bitmap_and 将nbits指定的位数按位与结果存放到dst。圆整到unsigned long。
  • bitmap_or 将nbits指定的位数按位或结果存放到dst。圆整到unsigned long。
  • bitmap_xor 将nbits指定的位数按位异或结果存放到dst。圆整到unsigned long。
  • bitmap_andnot 根据nbits指定的位数, 将src1按位与上src2的按位非,结果存放到dst。圆整到unsigned long。
  • bitmap_complement 根据nbits指定的位数, 按位取反后存放到dst。精确到位。
  • bitmap_equal 比较nbits指定的位数,如果这些为全部相同返回1,否则返回0。精确到位。
  • bitmap_intersects 比较nbits指定的位数中是否有重合(相交Overlap)的1比特位,也即src1和src2中有共同设置为1的标志位。有则返回1,否则返回0。精确到位。
  • bitmap_subset src1的nbits指定位数中设置1的比特位是src2中nbits指定位数中设置1的比特的子集,则返回1,否则返回0。精确到位。
  • bitmap_empty 测试src中的低nbits位是否全为0,是则返回1,否则返回0。精确到位。
  • bitmap_full 测试src中的低nbits位是否全为1,是则返回1,否则返回0。精确到位。
  • bitmap_weight 返回低nbits位的汉明重量(Hamming Weight)。
  • bitmap_shift_right 逻辑右移n位,左边补0。n可以大于nbits数。圆整到unsigned long。
  • bitmap_shift_left 逻辑左移n位,右边补0。n可以大于nbits数。圆整到unsigned long。
 

linux tricks 之 bitmap分析.的更多相关文章

  1. 网易视频云技术分享:linux软raid的bitmap分析

    网易视频云是网易倾力打造的一款基于云计算的分布式多媒体处理集群和专业音视频技术,提供稳定流畅.低时延.高并发的视频直播.录制.存储.转码及点播等音视频的PAAS服务,在线教育.远程医疗.娱乐秀场.在线 ...

  2. Linux内核源代码情景分析系列

    http://blog.sina.com.cn/s/blog_6b94d5680101vfqv.html Linux内核源代码情景分析---第五章 文件系统  5.1 概述 构成一个操作系统最重要的就 ...

  3. Linux内核源码分析之setup_arch (四)

    前言 Linux内核源码分析之setup_arch (三) 基本上把setup_arch主要的函数都分析了,由于距离上一篇时间比较久了,所以这里重新贴一下大致的流程图,本文主要分析的是bootmem_ ...

  4. Android/Linux下CGroup框架分析及其使用

    1 cgroup介绍 CGroup是control group的简称,它为Linux kernel提供一种任务聚集和划分的机制,可以限制.记录.隔离进程组(process groups)所使用的资源( ...

  5. Linux Kernel Oops异常分析

    1.PowerPC小系统内核异常分析 1.1  异常打印 Unable to handle kernel paging request for data at address 0x36fef31eFa ...

  6. 20169212《Linux内核原理与分析》课程总结

    20169212<Linux内核原理与分析>课程总结 每周作业链接汇总 第一周作业:完成linux基础入门实验,了解一些基础的命令操作. 第二周作业:学习MOOC课程--计算机是如何工作的 ...

  7. 1.linux服务器的性能分析与优化

    [教程主题]:1.linux服务器的性能分析与优化 [课程录制]: 创E [主要内容] [1]影响Linux服务器性能的因素 操作系统级 CPU 目前大部分CPU在同一时间只能运行一个线程,超线程的处 ...

  8. 20169212《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 这一周学习了MOOCLinux内核分析的第一讲,计算机是如何工作的?由于本科对相关知识的不熟悉,所以感觉有的知识理解起来了有一定的难度,不过多查查资 ...

  9. Linux系统日志及日志分析

    Linux系统日志及日志分析   Linux系统拥有非常灵活和强大的日志功能,可以保存几乎所有的操作记录,并可以从中检索出我们需要的信息. 大部分Linux发行版默认的日志守护进程为 syslog,位 ...

随机推荐

  1. linux 搭建nginx环境(centos6.5)

    1.rpm -ivh http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rp ...

  2. mysqldump命令介绍

    命令行下具体用法如下: mysqldump -u用戶名 -p密码 数据库名 表名 > 脚本名; 1.导出单个数据库的所有表的数据和结构 mysqldump -h localhost -uroot ...

  3. angular问题总结与反思

    因为工作中实际开发需要,才开始接触angular框架.从当初的比葫芦画瓢,被各种问题.概念折磨摧残,到现在有一定的了解认识,觉得有必要将自己的认识进行简单的总结.不到位的地方还望多多包涵. 1.双向数 ...

  4. 第13章 使用Bind提供域名解析服务

    章节简述: 本章节将让您理解DNS服务程序的原理,学习正向解析与反向解析实验,掌握DNS主服务器.从服务器.缓存服务器的部署方法. 够熟练配置区域信息文件与区域数据文件,以及通过使用分离解析技术让不同 ...

  5. 修改 ~/.bashrc显示 git 当前分支

    vim ~/.bashrc # git branch show configuration PS1="\\w:\$(git branch 2>/dev/null | grep '^*' ...

  6. MySQL的分页

    有朋友问: MySQL的分页似乎一直是个问题,有什么优化方法吗?网上看到网上推荐了一些分页方法,但似乎不太可行,你能点评一下吗? 方法1: 直接使用数据库提供的SQL语句 ---语句样式: MySQL ...

  7. WinAPI: ExtCreateRegion - 区域变换

    转载:http://www.cnblogs.com/del/archive/2008/06/03/1212534.html 相似函数: SetWorldTransform 本例效果图: 代码文件: u ...

  8. python4delphi import lxml pandas 出错的小结

    环境: 1.win10 64位 2.delphi xe8 3.python2.7 4.python4delphi  (svn 2015-03-21 发布的83版本号) 5.lxml 3.4.4(通过p ...

  9. android 自定义Dialog背景透明及显示位置设置

    先贴一下显示效果图,仅作参考: 代码如下: 1.自定义Dialog public class SelectDialog extends AlertDialog{ public SelectDialog ...

  10. php远程抓取网站图片并保存

    以前看到网上别人说写程序抓取网页图片的,感觉挺神奇,心想什么时候我自己也写一个抓取图片的方法! 刚好这两天没什么事,就参考了网上一个php抓取图片代码,重点借鉴了 匹配img标签和其src属性正则的写 ...