LWN在 RCU 上给出了以下示例:
订阅受 RCU 保护的 hlist 也类似于循环列表:
1 rcu_read_lock(); 2 hlist_for_each_entry_rcu(p, q, head, list) { 3 do_something_with(p->a, p->b, p->c); 4 } 5 rcu_read_unlock();
快速测验 3:当 list_for_each_entry_rcu() 只需要一个指针时,为什么我们需要将两个指针传递给 hlist_for_each_entry_rcu()?
回答: 因为在 hlist 中需要检查 NULL 而不是遇到头部。(尝试编写一个单指针 hlist_for_each_entry_rcu()。如果你想出了一个很好的解决方案,那将是一件非常好的事情!)
我认为它必须引用旧版本的 hlist_for_each_entry_rcu() 因为当前版本(3.13.0)在rculist.h
标题中实际上提出了hlist_for_each_entry_rcu
采用 3 个参数的定义,因此不需要额外的第 4 个指针并且似乎并不难发明:
#define hlist_for_each_entry_rcu(pos, head, member) \
for (pos = hlist_entry_safe (rcu_dereference_raw(hlist_first_rcu(head)),\
typeof(*(pos)), member); \
pos; \
pos = hlist_entry_safe(rcu_dereference_raw(hlist_next_rcu(\
&(pos)->member)), typeof(*(pos)), member))
我是否遗漏了当前 rculist.h 中给出的某些内容或更高版本是一件非常好的事情?
我们可以看到在__rcu_dereference_check
创建附加指针的地方发生了一些微妙的事情:
#define rcu_dereference_raw(p) rcu_dereference_check(p, 1) /*@@@ needed? @@@*/
#define rcu_dereference_check(p, c) \
__rcu_dereference_check((p), rcu_read_lock_held() || (c), __rcu)
#define __rcu_dereference_check(p, c, space) \
({ \
typeof(*p) *_________p1 = (typeof(*p)*__force )ACCESS_ONCE(p); \
rcu_lockdep_assert(c, "suspicious rcu_dereference_check()" \
" usage"); \
rcu_dereference_sparse(p, space); \
smp_read_barrier_depends(); \
((typeof(*p) __force __kernel *)(_________p1)); \