2008年4月1日 星期二

mb(), wmb(), rmb

這幾天又發現了幾個新東西, 以前沒注意到的 - mb(). rmb(), wmb(). 依序是 memory barrier, read memory barrier, write memory barrier.

看到之後翻了翻 Linux device driver, 2nd edition. 喔... 原來是降子的啊... 意思是說用來提醒 compiler 在這些個 mb function 前的 memory operation 要先做完, 之後的動作才可以做... 就是讓 optimization 不要自作主張, 把該先寫進(或讀入) memory 的動作給搬到後面去了...

例如:

writel(addr, val);
wmb()
val = readl(addr);

這樣就會 force compiler 在 wmb() 前的 writel 動作必須先做完, 之後的 readl 才會有意義...

但我卻發現 ARM 的 wmb(), rmb(), mb() 似乎沒有意義?? in include/asm-arm/system.h:

#if __LINUX_ARM_ARCH__ >= 6
#define mb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \
: : "r" (0) : "memory")
#else
#define mb() __asm__ __volatile__ ("" : : : "memory")
#endif
#define rmb() mb()
#define wmb() mb()

要到 ARMv6 以上的才會透過 coprocessor 15 force flush memory (? 不清楚, 沒用過 ARMv6). 看了一下 MIPS 的 code (include/asm-mips/system.h)

#define __sync() \
__asm__ __volatile__( \
".set push\n\t" \
".set noreorder\n\t" \
".set mips2\n\t" \
"sync\n\t" \
".set pop" \
: /* no output */ \
: /* no input */ \
: "memory")
#define fast_wmb() __sync()
#define fast_rmb() __sync()
#define fast_mb() __sync()
#define wmb() fast_wmb()
#define rmb() fast_rmb()
#define mb() fast_mb()

wmb(), rmb(), mb() 真的會去做 sync 動作...

怪怪的, ARM 的東西好像缺東缺西的... @_@

沒有留言: