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.

+3


source to share


4 answers


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;
}

      

+2


source


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))

      

+2


source


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;                              \
})

      

+1


source


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)

      

0


source







All Articles