【发布时间】:2011-09-27 04:21:04
【问题描述】:
最近在看一些Linux内核空间的代码,看到了这个
uint64_t used;
uint64_t blocked;
used = atomic64_read(&g_variable->used); //#1
barrier(); //#2
blocked = atomic64_read(&g_variable->blocked); //#3
这段代码sn-p的语义是什么?它是否确保 #1 在 #3 之前由 #2 执行。 但我有点困惑,因为
#A在64位平台,atomic64_read宏扩展为
used = (&g_variable->used)->counter // where counter is volatile.
在 32 位平台中,转换为使用锁 cmpxchg8b。我假设这两个具有相同的语义,对于 64 位版本,我认为这意味着:
- all-or-nothing,我们可以排除地址未对齐且字长大于 CPU 原生字长的情况。
- 无优化,强制 CPU 从内存位置读取。
atomic64_read 没有保留读取顺序的语义!!!见this
#B barrier 宏定义为
/* Optimization barrier */
/* The "volatile" is due to gcc bugs */
#define barrier() __asm__ __volatile__("": : :"memory")
来自wiki this 只是阻止gcc 编译器 重新排序读取和写入。
我很困惑的是它如何禁用 CPU 的重新排序优化?另外,我可以认为屏障宏是全栅栏吗?
【问题讨论】:
-
只有我一个人,或者这个问题可以压缩为“这个barrier()宏是如何工作的?” ?
-
我认为将
atomix...考虑在内很重要;也就是说——当 not 使用atomic...访问方法时是否存在语义差异?它是否取决于内存模型(强与弱)?一个或另一个是否意味着缓存刷新?等等等等。 -
@ptx,atomix是什么意思?任何参考
-
@Nicholas,也许,但这个简单的问题可能会因为没有表现出研究努力而被否决。
标签: linux multithreading concurrency atomic barrier