Linux设备驱动程序 之 RCU机制
读取-复制-更新(read-copy-update,RCU)是一种高级的互斥机制,在正确的条件下,可以获得高的性能;
RCU对它保护的数据结构做了一些限定,它针对经常发生读而很少发生写的情况做了优化,被保护的资源应该通过指针访问,而对这些资源的引用必须仅由原子代码拥有,在RCU保护的代码范围内不能进入睡眠状态;在修改该数据结构时,写入线程首先复制,然后修改副本,之后用新的版本替换相关指针,当内核确信老的版本上没有其他引用时,就可以释放老的版本了;
使用RCU的代码应该包含<linux/rcupdate.h>头文件;
RCU读操作的使用方法如下,注意反引用的指针不能在RCU锁之外使用;
rcu_read_lock(); p = rcu_dereference(ptr);
if (p != NULL) {
/* 读取操作 */
} rcu_read_unlock();
RCU写操作的使用方法如下,首先需要分配一个新的结构,如果必要则从旧的结构中复制数据,然后将读取代码能看到的指针替换掉;
struct some_struct * new_ptr = kmalloc(...); new_prt->xxx = xx; rcu_assign_pointer(ptr, new_ptr);
在写端完成之后,剩下的工作就是释放旧的数据结构;当然,这时其他处理器上运行的代码可能扔在引用旧的数据,因此不能立即释放旧的结构;写入代码必须等待直到能够确信不存在这样的引用;
因为拥有对该数据结构的引用的代码都必须是原子的,因此我们可以知道,一旦系统中的每个处理器都至少调用一次后,所有的引用都会消失;因此,RCU所做的就是,设置一个回调函数并等待所有的处理器被调度,之后由回调函数完成清理工作;
RCU提供了两个函数分别为同步等待所有读取结束和异步等待读取结束后释放旧结构资源;
同步:synchronize_rcu(),修改之后调用该函数等待所有读引引用结束,在函数返回之后进行旧资源的释放;
void synchronize_rcu(void);
异步:call_rcu(),通过该函数注册一个释放旧资源的回调函数,在所有的读访问完成之后,回调注册函数,进行旧资源的释放;
void call_rcu(struct rcu_head *head, rcu_callback_t func);
Linux设备驱动程序 之 RCU机制的更多相关文章
- 【转】linux设备驱动程序中的阻塞机制
原文网址:http://www.cnblogs.com/geneil/archive/2011/12/04/2275272.html 阻塞与非阻塞是设备访问的两种方式.在写阻塞与非阻塞的驱动程序时,经 ...
- 再谈Linux内核中的RCU机制
转自:http://blog.chinaunix.net/uid-23769728-id-3080134.html RCU的设计思想比较明确,通过新老指针替换的方式来实现免锁方式的共享保护.但是具体到 ...
- Linux设备驱动程序学习之分配内存
内核为设备驱动提供了一个统一的内存管理接口,所以模块无需涉及分段和分页等问题. 我已经在第一个scull模块中使用了 kmalloc 和 kfree 来分配和释放内存空间. kmalloc 函数内幕 ...
- Linux设备驱动程序学习----1.设备驱动程序简介
设备驱动程序简介 更多内容请参考Linux设备驱动程序学习----目录 1. 简介 Linux系统的优点是,系统内部实现细节对所有人都是公开的.Linux内核由大量复杂的代码组成,设备驱动程序可以 ...
- linux设备驱动程序-设备树(3)-设备树多级子节点的转换
linux设备驱动程序--设备树多级子节点的转换 在上一章:设备树处理之--device_node转换成platform_device中,有提到在设备树的device_node到platform_de ...
- linux设备驱动程序-i2c(2)-adapter和设备树的解析
linux设备驱动程序-i2c(2)-adapter和设备树的解析 (注: 基于beagle bone green开发板,linux4.14内核版本) 在本系列linux内核i2c框架的前两篇,分别讲 ...
- linux设备驱动程序-i2c(1):i2c总线的添加与实现
linux设备驱动程序-i2c(1):i2c总线的添加与实现 (基于4.14内核版本) 在上一章节linux设备驱动程序-i2c(0)-i2c设备驱动源码实现中,我们演示了i2c设备驱动程序的源码实现 ...
- Linux设备驱动之semaphore机制【转】
转自:http://blog.csdn.net/xiao229404041/article/details/7031776 Linux设备驱动之semaphore机制在Linux系统中,信号号是一种重 ...
- linux设备驱动程序该添加哪些头文件以及驱动常用头文件介绍(转)
原文链接:http://blog.chinaunix.net/uid-22609852-id-3506475.html 驱动常用头文件介绍 #include <linux/***.h> 是 ...
随机推荐
- 【ES6 】Promise
Promise对象定义: 用来处理异步编程 Promise对象的特点 对象的状态不受外界影响 一旦状态改变,就不会再变,任何时候都可以得到这个结果 Promise对象的状态 pending(进行中) ...
- 在开源UOJ的导航栏中添加新页面链接
前言 刚用开源UOJ搭建OJ成功时就想在导航栏那里添加一个站内页面链接,无奈当时乱搞水平低,网上也没有教程,不晓得怎么弄 今天突然来了闲情乱搞一通,结果还真乱搞成了...特意写下为后来人少走点弯路 前 ...
- [NOIP10.3模拟赛]3.w题解--神奇树形DP
题目链接: 咕 闲扯: 这题考场上把子任务都敲满了,5个namespace,400行11k 结果爆0了哈哈,因为写了个假快读只能读入一位数,所以手测数据都过了,交上去全TLE了 把边分成三类:0. 需 ...
- mybatis+Oracle 批量插入数据,有数据做更新操作
<!-- 批量添加 --> <insert id="batchAdd" parameterType="java.util.List"& ...
- asp.net 设计音乐网站
第一步 收集资料 http://www.logoko.com.cn/ --设计logo网站 设计音乐文档 https://wenku.baidu.com/view/3d957617f18583 ...
- Hadoop_21_MapReduce程序实现Join功能
1.序列化与Writable接口 1.1.hadoop的序列化格式 序列化和反序列化就是结构化对象和字节流之间的转换,主要用在内部进程的通讯和持久化存储方面 hadoop在节点间的内部通讯使用的是RP ...
- new Function()语法
函数的语法: let func = new Function(...args, body); 历史原因,参数也可以以逗号分隔的列表的形式给出,这三个意思相同: new Function('a', 'b ...
- Matlab---读取 .txt文件
Matlab读取 .txt文件 这里提供两种方法:1,load()函数.2,importdata()函数. ---------------------------------------------- ...
- 洛谷 P2765 魔术球问题 (dinic求最大流,最小边覆盖)
P2765 魔术球问题 题目描述 «问题描述: 假设有n根柱子,现要按下述规则在这n根柱子中依次放入编号为1,2,3,...的球. (1)每次只能在某根柱子的最上面放球. (2)在同一根柱子中,任何2 ...
- 简单的jquery进度条插件LineProgressbar.js,myProgress.js
参考 http://www.lanrenzhijia.com/jquery/4121.html demo下载 <script src="js/jquery.lineProgress ...