作者:睡眠女孩在外面的世界_988 | 来源:互联网 | 2023-02-01 17:58
核心代码片段transactionid的重要作用准备工作L2504-L2507barrierL2518内核per-cpu变量是没那么简单的一件事情,这和per-thread即thr
- 核心代码片段
- transaction id的重要作用
- 准备工作 L2504-L2507
- barrier L2518
内核per-cpu变量是没那么简单的一件事情,这和per-thread即thread local data完全是两个概念!!
核心代码片段
transaction id的重要作用
以及 L2521 注释
cmpxchg的每个CPU core上的每次操作都有唯一的tid来标识
准备工作 L2504-L2507
保证线程栈局部变量 tid 和 c是一致的,
可能不一致的原因:
- 当前线程thread1可能会被thread2抢占,而thread2恰好在当前CPU上执行了slab_alloc_node,那么s->cpu_slab->tid将被更新
- 当前线程thread1执行了L2505赋值tid之后,可能迁移到其他CPU上去执行, L2495-L2502的注释就是在说这事!!
barrier L2518
barrier 的所有功能分析可参见:
http://blog.csdn.net/cyx1231st/article/details/9262893
内存屏障主要解决了两个问题:单处理器下的乱序问题和多处理器下的内存同步问题。
http://blog.chinaunix.net/uid-9918720-id-1640912.html
barrier的必要性:
- 局部变量tid和object、page“看起来”没有任何依赖关系
- 因此编译器和CPU的乱序执行都可能会导致先write object、page再write tid
- 但实际必须先write tid,原因是
- 假设先写object、page,此时线程thread1被thread2抢占,而thread2恰好在当前CPU上执行了slab_alloc_node,那么c->tid、c->freelist、c->page将被更新,再切回thread1设置局部变量tid = c->tid,随后执行cmpxchg时必将成功,因为 tid == c->tid,而此时thread1的object和page明显不是最新!!!tid也就发挥不了应有的作用!!!
- 而假设先写tid,此时线程thread1被thread2抢占,而thread2恰好在当前CPU上执行了slab_alloc_node,那么c->tid、c->freelist、c->page将被更新,再切回thread1设置局部变量object和page,随后执行cmpxchg时必将失败,因为 tid != c->tid,然后此时我只需要goto redo即可!!!参见L2516注释