Linux内核的WRITE_ONCE函数分析

Linux kernel中list.h中 链表的初始化函数如下

static inline void INIT_LIST_HEAD(struct list_head *list)
{
    WRITE_ONCE(list->next, list);
    list->prev = list;

}

上面一段代码的作用是初始化链表,使前向指针和后向指针分别指向list自己。

不理解WRITE_ONCE()函数是干嘛的

转到WRITE_ONCE()函数,如下

#define WRITE_ONCE(var, val) \

    (*((volatile typeof(val) *)(&(var))) = (val))

volatile的作用是作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值。这与上篇的mesi协议有关

国外网站的回答是这样的

The ACCESS_ONCE macro is used in situations where a value is being retrieved from a storage location that is known (or suspected) to be volatile, but is not typed as such. The purpose is to retrieve the current value of the storage location in such a way as to defeat an optimising compiler that might otherwise cache the value in a register, or not even provide a storage location at all.
The construct as written applies the 'volatile' to the storage location indirectly by declaring a suitably typed pointer to that location. As per the C standard, this mandates that the object be evaluated strictly according to the rules of the abstract machine.
Your proposed modification would not apply volatile to the storage location, so it would not achieve this purpose. The value retrieval could be subject to optimisation.

Incidentally, I regard this as a model of conciseness for the stated purpose. I reserve complex for far worse things than this.

大概是这么个意思,*((volatile typeof(val) *)(&(var))可以保证var在多线程下被其它函数调用变量时不会出错。具体详情可以参考我前面一篇文章 缓存一致性协议(MESI协议)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值