![](/img/trans.png)
[英]Can rcu_assign_pointer() be used between rcu_read_lock() and rcu_read_unlock()?
[英]Nesting of rcu_read_locks
我将RCU保护的指针MyStruct *
存储在RCU保护的哈希表MyHash
。 通过哈希表读取/更新MyStruct
,如下所示。
rcu_read_lock() /* For hashtable 'MyHash' */
hash_for_each_possible_rcu(MyHash, obj, member, key)
{
rcu_read_lock(); /* For RCU protected data(MyStruct*) stored in hashtable */
Mystruct* s = rcu_dereference_pointer(obj->s);
if(s)
{
s->read++;
}
rcu_read_unlock(); /* For RCU protected data(MyStruct*) stored in hashtable */
}
rcu_read_unlock() /* For hashtable 'MyHash'*/
请注意, MyStruct
本身是另一个RCU保护列表的一部分(即它是另一个列表的RCU保护节点),该列表存储在MyHash
以加快查找速度。
据我了解,需要rcu_read_lock
来确保在所有读取端关键部分都完成之前,任何编写器更新都不会释放内存。 那么,是否真的有必要嵌套rcu_read_lock
或仅具有外部rcu_read_lock
/ rcu_read_unlock
就足够了?
IOW,由于RCU锁没有绑定到任何单个对象,当一起访问多个受RCU保护的对象时,我们真的需要嵌套的rcu锁吗?
不,嵌套rcu_read_lock()
不是必需的 。
与其他“嵌套”关键部分类似,嵌套的rcu_read_lock
的唯一作用是增加锁定级别。 也就是说,进一步的rcu_read_unlock
不会立即结束关键部分,而只是将锁定级别恢复到原来的水平。
但是,支持嵌套锁定被视为RCU锁定机制的优点 。 支持嵌套操作后,您可以彼此独立地开发组件。
例如,您可能具有object_increment
函数,可以在没有RCU锁定的情况下安全地调用该函数:
void object_increment(Object obj)
{
rcu_read_lock();
Mystruct* s = obj->s;
if(s)
{
s->read++;
}
rcu_read_unlock();
}
然后在RCU锁定下调用此函数:
rcu_read_lock(); /* For hashtable 'MyHash' */
hash_for_each_possible_rcu(MyHash, obj, member, key)
{
// It is perfectly valid to use the function even with RCU lock already taken
object_increment(obj);
}
rcu_read_unlock(); /* For hashtable 'MyHash'*/
简单设计几乎总是胜过嵌套调用rcu_read_lock
性能rcu_read_lock
。
如果没有嵌套调用,则需要使用RCU锁来实现另一组件的功能以进行访问:
void object_increment_locked(Object obj)
{
Mystruct* s = obj->s;
if(s)
{
s->read++;
}
}
并仔细选择在具体情况下要使用的功能-锁定或非锁定:
rcu_read_lock(); /* For hashtable 'MyHash' */
hash_for_each_possible_rcu(MyHash, obj, member, key)
{
// Already have a lock taken, so use _locked version of the function.
object_increment_locked(obj);
}
rcu_read_unlock(); /* For hashtable 'MyHash'*/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.