Edw*_*rdH 15 c atomic volatile linux-kernel
最近,我已经深入研究了原子读写的Linux内核实现,并提出了一些问题.
首先是ia64架构的相关代码:
typedef struct {
int counter;
} atomic_t;
#define atomic_read(v) (*(volatile int *)&(v)->counter)
#define atomic64_read(v) (*(volatile long *)&(v)->counter)
#define atomic_set(v,i) (((v)->counter) = (i))
#define atomic64_set(v,i) (((v)->counter) = (i))
Run Code Online (Sandbox Code Playgroud)
对于读取和写入操作,似乎采用直接方法来读取或写入变量.除非在某处有另一个技巧,否则我不明白这个操作在汇编域中是否具有原子性的保证.我想一个明显的答案是,这样的操作转换为一个程序集操作码,但即便如此,在考虑不同的内存缓存级别(或其他优化)时,如何保证?
在读取宏上,volatile类型用于转换技巧.任何人都知道这会如何影响这里的原子性?(注意,它不用于写操作)
Mah*_*dsi 14
我认为你误解了"非常模糊"的"原子"和"易变"这个词.Atomic只是意味着单词将以原子方式读取或写入(一步完成,并保证此存储器位置的内容始终为一个写入或另一个,而不是介于两者之间).并且volatile
关键字告诉编译器由于先前的读/写(从根本上说,永远不会优化掉读取),因此永远不会假设该位置的数据.
"原子"和"易变"这两个词在这里并不意味着存在任何形式的内存同步.既不暗示任何读/写障碍或围栏.关于内存和缓存一致性,没有任何保证.这些功能在软件级别基本上只是原子功能,硬件可以根据其认为合适的优化/替代.
现在,为什么简单的阅读就足够了:每个架构的内存模型都不同.许多体系结构可以保证对与某个字节偏移量对齐的数据进行原子读取或写入,或者长度为x个字等,并且因CPU而异.Linux内核包含许多针对不同体系结构的定义,这些体系允许它在没有任何原子调用的情况下(CMPXCHG
基本上)在平台上进行保证(有时甚至仅在实践中,即使实际上他们的规范说实际上并不保证)原子读/写.
至于volatile
,虽然除非你访问内存映射IO,否则一般不需要它,但这一切都取决于调用atomic_read
和atomic_write
调用宏的时间/地点/原因.许多编译器会(虽然它不是在C规格设定)产生volatile变量的内存屏障/栅栏(GCC,把我的头顶部,是一个.MSVC不肯定的.).虽然这通常意味着对此变量的所有读/写现在都可以正式免除任何编译器优化,在这种情况下,通过创建"虚拟"volatile变量,只有这个特定的读/写实例才是优化的优化并重新订购.