在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;
希望各位大神不吝赐教,在下先行谢过!
数组的其他元素都是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;
非常感谢,您的回答完美地解决了我的问题。
至于为什么写成伪代码,主要是为了突出“数组大小是通多(NR_CPUS/32)上取整得到的”这一事实。
再次感谢您的精彩解答!