cpu位图
SMP处理器中要用到cpu位图,用来维护系统内CPU的状态信息,具有代表性的有:
cpu_possible_map、cpu_online_map、cpu_present_map。
static DECLARE_BITMAP(cpu_possible_bits, CONFIG_NR_CPUS) __read_mostly
static DECLARE_BITMAP(cpu_online_bits, CONFIG_NR_CPUS) __read_mostly
static DECLARE_BITMAP(cpu_present_bits, CONFIG_NR_CPUS) __read_mostly
DECLARE_BITMAP宏定义如下
#define DECLARE_BITMAP(name,bits) \
unsigned long name[BITS_TO_LONGS(bits)]
所以上面定义了三个unsigned long数组,数组大小有BITS_TO_LONGS宏确定,1~31个cpu,则为1;32~63个cpu,则为2。
目前的多核处理器还没有超过31个的,所以这个数组大小一般为1.
unsigned long cpu_possible_map[BITS_TO_LONGS(CONFIG_NR_CPUS)]
unsigned long cpu_online_map[BITS_TO_LONGS(CONFIG_NR_CPUS)]
unsigned long cpu_present_map [BITS_TO_LONGS(CONFIG_NR_CPUS)]
内核中还是用下面的一种结构体,用来表示cpu位图,于上面的结构基本等价。
typedef struct cpumask { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t;
/*
struct cpumask {
unsigned long bits[BITS_TO_LONGS(NR_CPUS)]
}
*/
并且定义了to_cpumask宏用于从bit_map数组转换到cpumask结构体。
const struct cpumask *const cpu_possible_mask = to_cpumask(cpu_possible_bits);
const struct cpumask *const cpu_online_mask = to_cpumask(cpu_online_bits);
const struct cpumask *const cpu_present_mask = to_cpumask(cpu_present_bits);
#define to_cpumask(bitmap) \
((struct cpumask *)( ? (bitmap) \
: (void *)sizeof(__check_is_bitmap(bitmap)))) static inline int __check_is_bitmap(const unsigned long *bitmap)
{
return ;
}
内核中bitmap的设置与清除
static inline void set_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
unsigned long flags; _atomic_spin_lock_irqsave(p, flags);
*p |= mask;
_atomic_spin_unlock_irqrestore(p, flags);
} static inline void clear_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
unsigned long flags; _atomic_spin_lock_irqsave(p, flags);
*p &= ~mask;
_atomic_spin_unlock_irqrestore(p, flags);
} static inline void change_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
unsigned long flags; _atomic_spin_lock_irqsave(p, flags);
*p ^= mask;
_atomic_spin_unlock_irqrestore(p, flags);
} static inline int test_and_set_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
unsigned long old;
unsigned long flags; _atomic_spin_lock_irqsave(p, flags);
old = *p;
*p = old | mask;
_atomic_spin_unlock_irqrestore(p, flags); return (old & mask) != ;
} static inline int test_and_clear_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
unsigned long old;
unsigned long flags; _atomic_spin_lock_irqsave(p, flags);
old = *p;
*p = old & ~mask;
_atomic_spin_unlock_irqrestore(p, flags); return (old & mask) != ;
} static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
unsigned long old;
unsigned long flags; _atomic_spin_lock_irqsave(p, flags);
old = *p;
*p = old ^ mask;
_atomic_spin_unlock_irqrestore(p, flags); return (old & mask) != ;
}
最后几个bitmap中常用的宏
#define BIT(nr) (1UL << (nr))
#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
#define BITS_PER_BYTE 8
#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
把位图中所有bit设置为1
static inline void bitmap_fill(unsigned long *dst, int nbits)
{
size_t nlongs = BITS_TO_LONGS(nbits);
if (!small_const_nbits(nbits)) {
int len = (nlongs - ) * sizeof(unsigned long);
memset(dst, 0xff, len);
}
dst[nlongs - ] = BITMAP_LAST_WORD_MASK(nbits);
}
上面用到两个宏,先判断nbis是否超过32,即表示位图的数组元素是否多余1个
#define small_const_nbits(nbits) \
(__builtin_constant_p(nbits) && (nbits) <= BITS_PER_LONG)
最后一个32位可能没有全用到,下面的后过滤出使用到的bit
#define BITMAP_LAST_WORD_MASK(nbits) \
( \
((nbits) % BITS_PER_LONG) ? \
(1UL<<((nbits) % BITS_PER_LONG))- : ~0UL \
)
遍历多cpu
#define for_each_possible_cpu(cpu) for_each_cpu((cpu), cpu_possible_mask)
展开为
/**
* for_each_cpu - iterate over every cpu in a mask
* @cpu: the (optionally unsigned) integer iterator
* @mask: the cpumask pointer
*
* After the loop, cpu is >= nr_cpu_ids.
*/
#define for_each_cpu(cpu, mask) \
for ((cpu) = -; \
(cpu) = cpumask_next((cpu), (mask)), \
(cpu) < nr_cpu_ids;)
/**
* cpumask_next - get the next cpu in a cpumask
* @n: the cpu prior to the place to search (ie. return will be > @n)
* @srcp: the cpumask pointer
*
* Returns >= nr_cpu_ids if no further cpus set.
*/
static inline unsigned int cpumask_next(int n, const struct cpumask *srcp)
{
/* -1 is a legal arg here. */
if (n != -)
cpumask_check(n);
return find_next_bit(cpumask_bits(srcp), nr_cpumask_bits, n+);
}
cpu位图的更多相关文章
- Linux CPU Hotplug CPU热插拔
http://blog.chinaunix.net/uid-15007890-id-106930.html CPU hotplug Support in Linux(tm) Kernel Linu ...
- linux tricks 之 bitmap分析.
------------------------------------------- 本文系作者原创, 欢迎大家转载! 转载请注明出处:netwalker.blog.chinaunix.net -- ...
- 【转】Linux模式设计5-位图操作
通过位图提供的两种状态可以在非常节约内存的情况下表示开关变量,并且同类这类变量可以紧凑而高效的统一进行处理.有很多内核子系统都需要位图的支持,但是不同的情况又需要不同的位图个数,比如SMP系统上的CP ...
- 浅析Linux的软中断的实现
參考: http://bbs.chinaunix.net/thread-2333484-1-1.html http://liu1227787871.blog.163.com/blog/static/2 ...
- Linux内核跟踪之trace框架分析【转】
转自:http://blog.chinaunix.net/uid-20543183-id-1930846.html ---------------------------------------- ...
- Linux内核跟踪之ring buffer的实现【转】
转自:http://blog.chinaunix.net/uid-20543183-id-1930845.html ---------------------------------------- ...
- ARM Linux内核源码剖析索引
start_kernel -->asm-offset.h 生成 -->proc_info_list -->machine_desc -->__vet_atags --> ...
- 扩展Linux网络栈
扩展Linux网络栈 来自Linux内核文档.之前看过这篇文章,一直好奇,问什么一条网络流会固定在一个CPU上进行处理,本文档可以解决这个疑问.为了更好地理解本文章中的功能,将这篇文章穿插入内. 简介 ...
- [源码解析] PyTorch 分布式(8) -------- DistributedDataParallel之论文篇
[源码解析] PyTorch 分布式(8) -------- DistributedDataParallel之论文篇 目录 [源码解析] PyTorch 分布式(8) -------- Distrib ...
随机推荐
- java preparement
1.建立链接 Connection conn = getDataSource().getConnection(); PreparedStatement ps = null; 2不自动 Commit 不 ...
- (转)nginx应用总结(1)--基础认识和应用参数优化配置
在linux系统下使用nginx作为web应用服务,用来提升网站访问速度的经验已五年多了,今天在此对nginx的使用做一简单总结. 一.nginx服务简介Nginx是一个高性能的HTTP和反向代理服务 ...
- [FACT_采购信息]增加了延期天数
[延期天数]是指的采购单上的货品交货日期 减 [厂家来货]单据货品第一次到货日期. [FACT_采购信息] SELECT p.[Purchase_ID] [采购单号ID], p.[Supply_No] ...
- C#高级语法
委托 委托就是指针函数,委托的定义与类的属性定义类似都必须在类的方法体进行. 委托的定义: class Program { //定义委托:委托不能在方法体内定义. public delegate st ...
- GDI绘制图形的使用_验证码
//创建GDI对象 Graphics g = this.CreateGraphics();// new Graphics(); //创建画笔对象 Pen pen = new Pen(Brushes.R ...
- springboot集成shiro实现权限认证
github:https://github.com/peterowang/shiro 基于上一篇:springboot集成shiro实现身份认证 1.加入UserController package ...
- JavaScript中登录名的正则表达式及解析(0基础)
简言 在JavaScript中,经常会用到正则表达式来进行模式匹配.例如,登录名验证,密码强度验证,字符串查找或替换等操作.现在就开始吧,零基础写出你的第一个正则表达式! 在做用户注册时,都会用到登录 ...
- 牛客NOIP提高组(二)题解
心路历程 预计得分:100 + 40 + 30 = 170 实际得分:100 + 30 + 0 = 130 T2有一个部分分的数组没开够RE了. T3好像是思路有点小问题.. 思路没问题,实现的时候一 ...
- 初识RatingBar
RatingBar,SeekBar和ProgressBar的子类 <RatingBar android:id="@+id/ratingBar2" android:layout ...
- 运行JavaWeb项目报错Access denied for user 'root'@'localhost' (using password: YES)
问题重现:(以下讨论范围仅限Windows环境): C:\AppServ\MySQL> mysql -u root -p Enter password: ERROR 1045 (28000): ...