首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Linux 2.6内核中新的锁机制--RCU(2)实现机制

Linux 2.6内核中新的锁机制--RCU(2)实现机制

三、RCU 实现机制按照第二节所讲原理,对于读者,RCU 仅需要抢占失效,因此获得读锁和释放读锁分别定义为:
1
2
#define rcu_read_lock()         preempt_disable()
#define rcu_read_unlock()       preempt_enable()




它们有一个变种:
1
2
#define rcu_read_lock_bh()      local_bh_disable()
#define rcu_read_unlock_bh()    local_bh_enable()




这个变种只在修改是通过 call_rcu_bh 进行的情况下使用,因为 call_rcu_bh将把 softirq 的执行完毕也认为是一个 quiescent state,因此如果修改是通过 call_rcu_bh 进行的,在进程上下文的读端临界区必须使用这一变种。
每一个 CPU 维护两个数据结构rcu_data,rcu_bh_data,它们用于保存回调函数,函数call_rcu和函数call_rcu_bh用户注册回调函数,前者把回调函数注册到rcu_data,而后者则把回调函数注册到rcu_bh_data,在每一个数据结构上,回调函数被组成一个链表,先注册的排在前头,后注册的排在末尾。
当在CPU上发生进程切换时,函数rcu_qsctr_inc将被调用以标记该CPU已经经历了一个quiescent state。该函数也会被时钟中断触发调用。
时钟中断触发垃圾收集器运行,它会检查:
  • 否在该CPU上有需要处理的回调函数并且已经经过一个grace period;
  • 否没有需要处理的回调函数但有注册的回调函数;
  • 否该CPU已经完成回调函数的处理;
  • 否该CPU正在等待一个quiescent state的到来;
如果以上四个条件只要有一个满足,它就调用函数rcu_check_callbacks。
函数rcu_check_callbacks首先检查该CPU是否经历了一个quiescent state,如果:
1.        当前进程运行在用户态;

2.        当前进程为idle且当前不处在运行softirq状态,也不处在运行IRQ处理函数的状态;
那么,该CPU已经经历了一个quiescent state,因此通过调用函数rcu_qsctr_inc标记该CPU的数据结构rcu_data和rcu_bh_data的标记字段passed_quiesc,以记录该CPU已经经历一个quiescent state。
否则,如果当前不处在运行softirq状态,那么,只标记该CPU的数据结构rcu_bh_data的标记字段passed_quiesc,以记录该CPU已经经历一个quiescent state。注意,该标记只对rcu_bh_data有效。
然后,函数rcu_check_callbacks将调用tasklet_schedule,它将调度为该CPU设置的tasklet rcu_tasklet,每一个CPU都有一个对应的rcu_tasklet。
在时钟中断返回后,rcu_tasklet将在softirq上下文被运行。
rcu_tasklet将运行函数rcu_process_callbacks,函数rcu_process_callbacks可能做以下事情:
1.        开始一个新的grace period;这通过调用函数rcu_start_batch实现。
2.        运行需要处理的回调函数;这通过调用函数rcu_do_batch实现。
3.        检查该CPU是否经历一个quiescent state;这通过函数rcu_check_quiescent_state实现
如果还没有开始grace period,就调用rcu_start_batch开始新的grace period。调用函数rcu_check_quiescent_state检查该CPU是否经历了一个quiescent state,如果是并且是最后一个经历quiescent state的CPU,那么就结束grace period,并开始新的grace period。如果有完成的grace period,那么就调用rcu_do_batch运行所有需要处理的回调函数。函数rcu_process_callbacks将对该CPU的两个数据结构rcu_data和rcu_bh_data执行上述操作。
返回列表