linux_rcu机制详解

linux_rcu机制详解

ID:19335732

大小:58.50 KB

页数:16页

时间:2018-10-01

linux_rcu机制详解_第1页
linux_rcu机制详解_第2页
linux_rcu机制详解_第3页
linux_rcu机制详解_第4页
linux_rcu机制详解_第5页
资源描述:

《linux_rcu机制详解》由会员上传分享,免费在线阅读,更多相关内容在应用文档-天天文库

1、一:前言RCU机制出现的比较早,只是在linuxkernel中一直到2.5版本的时候才被采用.关于RCU机制,这里就不做过多的介绍了,网上有很多有关RCU介绍和使用的文档.请自行查阅.本文主要是从linuxkernel源代码的角度.来分析RCU的实现.在讨论RCU的实现之前.有必要重申以下几点:1:RCU使用在读者多而写者少的情况.RCU和读写锁相似.但RCU的读者占锁没有任何的系统开销.写者与写写者之间必须要保持同步,且写者必须要等它之前的读者全部都退出之后才能释放之前的资源.2:RCU保护的是指针.这一点尤其重要.因为指针赋值是一条单指令.也就是说是一个原子操作.因它更改指针

2、指向没必要考虑它的同步.只需要考虑cache的影响.3:读者是可以嵌套的.也就是说rcu_read_lock()可以嵌套调用.4:读者在持有rcu_read_lock()的时候,不能发生进程上下文切换.否则,因为写者需要要等待读者完成,写者进程也会一直被阻塞.以下的代码是基于linuxkernel2.6.26二:使用RCU的实例Linuxkernel中自己附带有详细的文档来介绍RCU,这些文档位于linux-2.6.26.3/Documentation/RCU.这些文档值得多花点时间去仔细研读一下.下面以whatisRCU.txt中的例子作为今天分析的起点:structfoo{ 

3、     inta;      charb;      longc;};DEFINE_SPINLOCK(foo_mutex);structfoo*gbl_foo;voidfoo_update_a(intnew_a){      structfoo*new_fp;      structfoo*old_fp;      new_fp=kmalloc(sizeof(*new_fp),GFP_KERNEL);      spin_lock(&foo_mutex);      old_fp=gbl_foo;      *new_fp=*old_fp;      new_fp->a=new

4、_a;      rcu_assign_pointer(gbl_foo,new_fp);      spin_unlock(&foo_mutex);      synchronize_rcu();      kfree(old_fp);}intfoo_get_a(void){      intretval;      rcu_read_lock();      retval=rcu_dereference(gbl_foo)->a;      rcu_read_unlock();      returnretval;}如上代码所示,RCU被用来保护全局指针structfoo*gbl

5、_foo.foo_get_a()用来从RCU保护的结构中取得gbl_foo的值.而foo_update_a()用来更新被RCU保护的gbl_foo的值.另外,我们思考一下,为什么要在foo_update_a()中使用自旋锁foo_mutex呢?假设中间没有使用自旋锁.那foo_update_a()的代码如下:voidfoo_update_a(intnew_a){      structfoo*new_fp;      structfoo*old_fp;      new_fp=kmalloc(sizeof(*new_fp),GFP_KERNEL);            old_

6、fp=gbl_foo;      1:-------------------------          *new_fp=*old_fp;      new_fp->a=new_a;      rcu_assign_pointer(gbl_foo,new_fp);            synchronize_rcu();      kfree(old_fp);}假设A进程在上图----标识处被B进程抢点.B进程也执行了goo_ipdate_a().等B执行完后,再切换回A进程.此时,A进程所持的old_fd实际上已经被B进程给释放掉了.此后A进程对old_fd的操作都是非法的

7、.另外,我们在上面也看到了几个有关RCU的核心API.它们为别是:rcu_read_lock()rcu_read_unlock()synchronize_rcu()rcu_assign_pointer()rcu_dereference()其中,rcu_read_lock()和rcu_read_unlock()用来保持一个读者的RCU临界区.在该临界区内不允许发生上下文切换.rcu_dereference():读者调用它来获得一个被RCU保护的指针.Rcu_assign_point

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。