Wrapping a read macro in c
There is a read macro as follows:
#define I915_READ16(reg) i915_read16(dev_priv, (reg))
#define I915_WRITE16(reg) i915_write16(dev_priv, (reg))
I want to measure the time elapsed with each of the read / write commands. I can easily do to write like this
#define I915_WRITE_NOTRACE(reg, val) \
do { \
__start_mmio(); \
writel(val, dev_priv->regs + (reg));\
_end_mmio(); \
} while(0)
where __start_mmio and __end_mmio are functions that measure time. But for reading, if I do the same, this macro will give me a compilation error because the macros are used like this:
val = I915_READ16(reg)
which will be decoded as
val = do {
__start_mmio();
readl(dev_priv->regs + (reg));
_end_mmio();
} while(0)
Definitely a compilation error.
Use this macro:
#define I915_READ_NOTRACE(reg) \
(start_mmio2() + readl(dev_priv->regs + (reg)) + end_mmio2())
where you define start_mmio2
and end_mmio2
as functions that return 0. For example:
static inline int start_mmio2(void)
{
__start_mmio();
return 0;
}
Create a built-in function instead of a macro;
inline int I915_READ16_NOTRACE(int reg) {
__start_mmio();
int result = readl(dev_priv->regs + (reg));
_end_mmio();
return result;
};
or if you have to make it a macro use comma notation like:
#define I915_READ16_NOTRACE(reg) \
((__start_mmio(),0) + readl(dev_priv->regs + (reg)) + (_end_mmio(),0))
Since it looks like for the linux kernel, we can use gcc extensions such as expressions:
#define I915_READ_NOTRACE(reg) ({ \
__start_mmio(); \
uint16_t val = I915_READ16(val); \
__end_mmio(); \
val; \
})
Pass the value val as an argument to your read wrapper macro.
#define I915_READ16_NOTRACE(reg, val) \
do { \
__start_mmio(); \
(val) = i915_read16(dev_priv, (reg)); \
_end_mmio(); \
} while(0)