有一个读取宏如下:
#define I915_READ16(reg) i915_read16(dev_priv, (reg))
#define I915_WRITE16(reg) i915_write16(dev_priv, (reg))
我想测量每个读/写命令所经过的时间。 我可以很容易地写如下
#define I915_WRITE_NOTRACE(reg, val) \
do { \
__start_mmio(); \
writel(val, dev_priv->regs + (reg));\
_end_mmio(); \
} while(0)
其中__start_mmio和__end_mmio是衡量时间的函数。 但是对于读取,如果我这样做,这个宏给我一个编译错误,因为宏使用如下:
val = I915_READ16(reg)
将被解码为
val = do {
__start_mmio();
readl(dev_priv->regs + (reg));
_end_mmio();
} while(0)
绝对是编译错误。
答案 0 :(得分:2)
创建内联函数而不是宏;
inline int I915_READ16_NOTRACE(int reg) {
__start_mmio();
int result = readl(dev_priv->regs + (reg));
_end_mmio();
return result;
};
或者如果你必须使它成为宏,请使用逗号表示法,例如;
#define I915_READ16_NOTRACE(reg) \
((__start_mmio(),0) + readl(dev_priv->regs + (reg)) + (_end_mmio(),0))
答案 1 :(得分:2)
使用此宏:
#define I915_READ_NOTRACE(reg) \
(start_mmio2() + readl(dev_priv->regs + (reg)) + end_mmio2())
您可以将start_mmio2
和end_mmio2
定义为返回0的函数。例如:
static inline int start_mmio2(void)
{
__start_mmio();
return 0;
}
答案 2 :(得分:1)
由于这似乎是针对Linux内核的,我们可以使用像statement expressions这样的gcc扩展:
#define I915_READ_NOTRACE(reg) ({ \
__start_mmio(); \
uint16_t val = I915_READ16(val); \
__end_mmio(); \
val; \
})
答案 3 :(得分:0)
将val作为参数传递给读包装宏。
#define I915_READ16_NOTRACE(reg, val) \
do { \
__start_mmio(); \
(val) = i915_read16(dev_priv, (reg)); \
_end_mmio(); \
} while(0)