typedef struct {
int counter;
} atomic_t;
static inline int atomic_read(const atomic_t *v)
{
return ACCESS_ONCE((v)->counter);
}
#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
ACCESS_ONCE
宏的目的是为了确保对 x
的访问(读取或写入)是不可分割的,也就是说,保证在读取或写入时,操作是原子的,不会被编译器的优化所影响。这通常用在多线程或者需要考虑中断的情况下,当你必须确保变量的值在被访问时没有被其他代码路径同时修改。
下面是对这个宏的解释:
*(volatile typeof(x) *)&(x)
:typeof(x)
:取得变量x
所代表的类型。(volatile typeof(x) *)
:这段代码将x
的地址转换为一个指向typeof(x)
类型的volatile
指针。volatile
关键字告诉编译器,每次访问这个变量时都需要从内存重新读取数据,这防止了编译器可能会做的任何优化,例如将变量值缓存在寄存器中。&
:取得变量x
的地址。*(...)
:对转换为volatile
类型的指针进行解引用操作,即 获取该地址上的值。
因此,ACCESS_ONCE(x)
宏实际上在提供对 x
的直接访问,同时通过将其作为 volatile
类型来抑制编译器的优化行为。这在并发编程中非常重要,因为这样的操作有可能改变多个线程的行为。 English
请注意,ACCESS_ONCE
宏通常用于内核或嵌入式系统编程,在普通的应用程序中并不常见。此外,随着编译器和处理器模型的发展,可能需要更先进的同步机制(如内存栅栏或原子操作)来保证操作的原子性和内存的一致性。