我有一个样板函数,可以在树状数据库中找到一个结构:
struct foo {
struct foo *child1; /* RCU-protected. */
struct foo *child2; /* RCU-protected. */
... /* Other stuff */
}
static struct foo *find_foo(int arg)
{
struct foo *parent;
... /* Do something to find parent. */
return rcu_dereference(parent->child1); /* or child2. Whatever. */
}
然后我有几个函数可以处理这个结果:
void a(int arg)
{
struct foo *bar;
rcu_read_lock();
bar = find_foo(arg);
... /* Read something from bar and do something with it. */
rcu_read_unlock();
}
然后我有一个更新器/回收器。它需要像“a”函数一样找到对象(假设它已经从外部互斥):
void c(int arg)
{
struct foo *bar;
bar = find_foo(arg);
... /* make a backup pointer of bar->child1. */
rcu_assign_pointer(bar->child1, ...);
... /* free the old child or whatever. */
}
我的问题是,rcu_dereference()
的文档说它必须从读取端关键部分(即在rcu_read_lock()
和之间rcu_read_unlock()
)中调用。c()
调用 . 违反了此规则find_foo()
。
我很犹豫要不要制作一个全新的版本,find_foo()
它使用rcu_dereference_protected()
而不是rcu_dereference()
,因为它有太多重复的代码,所以我想知道这个实现c()
是否合法:
void c(int arg)
{
struct foo *bar;
rcu_read_lock();
bar = find_foo(arg);
bar = rcu_dereference_protected(bar, ...); /* THIS. */
rcu_read_unlock();
... /* make a backup pointer of bar->child1. */
rcu_assign_pointer(bar->child1, ...);
... /* free the old child or whatever. */
}
如果这不合法,我应该如何混合阅读器和更新程序代码?