下面是 Linux Kernel 中用于 per-cpu 贵重物品的技巧。正如评论所说,它可以实现这两个目标:
1.执行范围。
2.确保唯一性,即使是静态的。
这是魔术的播放方式(为简单起见,我替换了一些宏):
/*
* __pcpu_scope_* dummy variable is used to enforce scope. It
* receives the static modifier when it's used in front of
* DEFINE_PER_CPU() and will trigger build failure if
* DECLARE_PER_CPU() is used for the same variable.
*
* __pcpu_unique_* dummy variable is used to enforce symbol uniqueness
* such that hidden weak symbol collision, which will cause unrelated
* variables to share the same address, can be detected during build.
*/
#define DECLARE_PER_CPU_SECTION(type, name, sec) \
extern __attribute__((section(".discard"), unused)) \
char __pcpu_scope_##name; \
extern __attribute__((section(sec))) __typeof__(type) name
#define DEFINE_PER_CPU_SECTION(type, name, sec) \
__attribute__((section(".discard"), unused)) char __pcpu_scope_##name; \
extern __attribute__((section(".discard"), unused)) \
char __pcpu_unique_##name; \
__attribute__((section(".discard"), unused)) char __pcpu_unique_##name; \
__attribute__((section(sec))) __attribute__((weak)) \
__typeof__(type) name
我的问题是
对于目标 #1。它如何强制执行范围?它是这样工作的:
当 DECLARE* 和 DECLARE* 存在于同一个翻译单元中时,它将相关变量转换为内部链接,因此,同一变量的任何额外 DECLARE* 都将触发构建失败(因为它们在链接上存在分歧)
但如果这是真的,那么
- 内部链接接收如何工作?从 C99 6.9.2.2(外部对象定义)开始,这仅发生在暂定定义中,但这种情况似乎不是暂定定义?
- 这不会打破“一个定义和多个声明都可以”的规则吗?
对于目标#2,两个__pcpu_unique_##name decalation(确切地说,一个是声明,另一个是定义)似乎与__pcpu_scope_##name发挥相同的作用,那么它如何帮助确保唯一性?
仅供参考,有问题的代码可以在这里查看:http: //lxr.linux.no/linux+v3.9/include/linux/percpu-defs.h#L61