首页新闻找找看学习计划

请教大家一个Linux内核中的C语言宏定义问题

0
悬赏园豆:10 [待解决问题]

在Linux内核中,有一个名为cpumask_t的数据结构,与该结构相关的定义如下:

 1  /*代码位置:include/linux/cpumask.h*/
 2   typedef struct { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t;
 3   
 4   /*代码位置:include/linux/types.h*/
 5   #define DECLARE_BITMAP(name,bits) \
 6       unsigned long name[BITS_TO_LONGS(bits)]
 7   
 8   /*代码位置:include/linux/bitops.h*/
 9   #define BITS_TO_LONGS(nr)    DIV_ROUND_UP(nr, BITS_PER_LONG)
10  
11  /*代码位置:include/linux/kernel.h*/
12  #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
13  
14  /*代码位置:include/asm-x86/types.h*/
15  #ifdef CONFIG_X86_32
16  # define BITS_PER_LONG 32
17  #else
18  # define BITS_PER_LONG 64
19  #endif

其中,NR_CPUS是一个常量。上面这些,在下都能看懂,转化为C语言伪代码就是

unsigned long size = (NR_CPUS+31)/32;
typedef struct{unsigned long bits[size];} cpumask_t;

这里BITS_PER_LONG取32,(NR_CPUS+31)/32就是对(NR_CPUS/32)上取整。

问题是,下面这个宏在下就看不懂了

#define CPU_MASK_NONE                            \
(cpumask_t) { {                                \
    [0 ... BITS_TO_LONGS(NR_CPUS)-1] =  0UL                \
} }

在下想请教各位大神,上面宏定义中的三个点"..."是什么意思啊?整个宏定义是什么意思?

为了向大家更清楚地说明问题,下面是内核代码中用CPU_MASK_NONE初始化cpumask_t的一个例子

cpumask_t populated = CPU_MASK_NONE;

希望各位大神不吝赐教,在下先行谢过!

同勉共进的主页 同勉共进 | 初学一级 | 园豆:171
提问于:2016-09-02 10:24
< >
分享
所有回答(2)
0

数组的其他元素都是0

悦光阴 | 园豆:2239 (老鸟四级) | 2016-09-02 12:14
0

linux 内核代码基于 GNU C提供的扩展语法编写的. 上面就是GNU C提供的指定范围初始化的扩展语法.

而在标准C中要求数组或结构变量的初使化值必须以固定的顺序出现.(C11 中现在也支持通过索引初始化了).

但在GNU C中,通过指定索引或结构域名,允许初始化值以任意顺序出现。

指定数组索引的方法是在初始化值前写 '[index] =',

要指定一个范围使用'[first ... last] ='的形式, 就是你所看见的那种方式.

 

关于GNU C / gcc编译器提供扩展语法, 更加详细的资料可以看下面链接

http://blog.csdn.net/wenxy1/article/details/5547575

另外问题, 对于C代码何必写伪代码 直接

typedef struct {

  unsigned long bits[(NR_CPUS+31)/32];

} cpumask_t;

 

 

喜欢兰花山丘 | 园豆:222 (菜鸟二级) | 2016-09-03 16:10

非常感谢,您的回答完美地解决了我的问题。

至于为什么写成伪代码,主要是为了突出“数组大小是通多(NR_CPUS/32)上取整得到的”这一事实。

再次感谢您的精彩解答!

支持(0) 反对(0) 同勉共进 | 园豆:171 (初学一级) | 2016-09-03 16:16
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册