快乐虾http://blog.csdn.net/lights_joy/lights@hb165.com本文适用于ADI bf561 DSP优视BF561EVB开发板uclinux-2008r1.5-rc3(smp patch)Visual DSP++ 5.0(update 5)欢迎转载,但请保留作者信息有一个错误:"../../linux-2.6.x/include/linux/rcupdate.h", line 124: cc0144:error: avalue of type "volatile __typeof__(struct rcu_data) *" cannot beused to initialize an entity of type "struct rcu_data *"struct rcu_data *rdp = &per_cpu(rcu_data, cpu);^错误指向的代码为:DECLARE_PER_CPU(struct rcu_data, rcu_data);/** Increment the quiescent state counter.* The counter is a bit degenerated: We do not need to know* how many quiescent states passed, just if there was at least* one since the start of the grace period. Thus just a flag.*/staticinlinevoid rcu_qsctr_inc(int cpu){struct rcu_data *rdp = &per_cpu(rcu_data, cpu);rdp->passed_quiesc = 1;}先看一下DECLARE_PER_CPU的定义:#define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name代入第一行就是:externstruct rcu_data per_cpu__ rcu_data;再看看per_cpu的定义:/* var is in discarded region: offset to particular copy we want */#define per_cpu(var, cpu) (*({/externint simple_identifier_##var(void);/RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu]); }))/* This macro obfuscates arithmetic on a variable address so that gccshouldn't recognize the original var, and make assumptions about it *//** Versions of the ppc64 compiler before 4.1 had a bug where use of* RELOC_HIDE could trash r30. The bug can be worked around by changing* the inline assembly constraint from =g to =r, in this particular* case either is valid.*/#define RELOC_HIDE(ptr, off)/({ unsignedlong __ptr;/__asm__ ("" : "=r"(__ptr) : "0"(ptr));/(__typeof__(ptr)) (__ptr + (off)); })从头到尾都没有出现volatile,奇怪?再看看rcu_data实际定义的地方:DEFINE_PER_CPU(struct rcu_data, rcu_data) = { 0L };使用了DEFINE_PER_CPU宏,看看它的定义:#define DEFINE_PER_CPU(type, name) /__attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name只不过是把这个结构体放在.data.percpu这个段里,也没有特别的地方。百思不得其解,先放过它,直接强制转换:/** Increment the quiescent state counter.* The counter is a bit degenerated: We do not need to know* how many quiescent states passed, just if there was at least* one since the start of the grace period. Thus just a flag.*/staticinlinevoid rcu_qsctr_inc(int cpu){struct rcu_data *rdp = (struct rcu_data *)&per_cpu(rcu_data, cpu);rdp->passed_quiesc = 1;}