帮同学宣传一下http://shop57644665.taobao.com/

Linux 中的 barrier

#define preempt_disable() \
do { \
inc_preempt_count(); \
barrier(); \
} while (0)

#define barrier() __asm__ __volatile__("": : :"memory")

#ifndef barrier
# define barrier() __memory_barrier()
#endif

memory_barrier 存在的原因是因为CPU的乱序执行技术。在操作系统层面上,我们有多任务,其中一个好处就是在等待磁盘等比较慢的设备反应的时候可以切换到其他任务执行, 而不是一直在那里干等浪费时间,同样,在 CPU 级别,从内存取一个数据也是非常慢的,为了避免空闲等待,可以在这个时候去分派其他指令的执行,就有可能造成乱序了,不过 CPU 最后会把得到的结果按照原来的顺序排列再返回回来,所以如果没有副作用的话,从外面是看不出来 CPU 有没有乱序执行的。

关于Memory   Barrier的时间序列有三条,这三条序列的第一条和最后一条在同一个CPU中是可以各自保证因果关系的,但是对于不同CPU来说,没有必然的因果关系而且三个序列都是独立的:
***   Sequence   of   CPU   committing   write   to   memory.
***   Sequence   of   CPU   perceiving   memory   change,   usually   delayed   and   out   of   order   as   the   actual   memroy   change.
***   Sequence   of   CPU   issuing   read.
Write   barrier:
保证write   barrier前的指令在sequence   of   CPU   committing   write   to   memory中一定出现在write   barrier后的指令之前。
Read   barrier:
Barrier的保证满足如下的rule。
***   首先保证在read   barrier之前的read肯定比barrier之后的read之后的指令早发出。
***   在sequence   of   CPU   perceiving   memory   change中查找read   barrier以前的read指令被issue的时间点。
***   找出最后的时间点PL。
***   把PL之前perceive到的所有memory   change找出。
***   检查这些memory   change实际commit到memory的时间,找到最后的时间点PC。
***   确保PC之前的所有address1   memory   change都被perceive到,才发出read   address1指令。
Read   depends   barrier
Barrier的保证满足如下的rule。
***   首先保证在read   barrier之前的dependent   read肯定比barrier之后的read之后的指令早发出——其实这一点无需由barrier保证,因为任何CPU都天然满足这一条。
***   在sequence   of   CPU   perceiving   memory   change中查找read   barrier以前的dependent   ***   read指令发生的时间点。
***   找出最后的时间点PL。
***   把PL之前perceive到的memory   change找出。
***   检查这些memory   change实际commit到memory的时间,找到最后的时间点PC。
***   确保PC之前的所有address1   memory   change都被perceive到,才发出read   address1指令