kfifo 的一些伪代码

 kfifo_len()
out = LOAD fifo->out
smp_rmb()
len = LOAD fifo->in - out kfifo_in() kfifo_out()
kfifo_len() kfifo_len() smp_mb() smp_rmb() off = LOAD fifo->in + off off = LOAD fifo->out + off /* memcpy */ /* memcpy */ smp_wmb() smp_mb() STORE fifo->in += off STORE fifo->out += off

kfifo_in 只修改 fifo->in 的值,含一个 STORE 指令,及若干 fifo->out fifo->in 的 LOAD 指令
kfifo_out 相反,只修改 kfifo->out 的值,同样含一个 STORE 指令及若干 LOAD 指令

把代码中的内存屏障去掉

kfifo_len()
out = LOAD fifo->out
/* smp_rmb() */
len = LOAD fifo->in - out kfifo_in() kfifo_out() kfifo_len() kfifo_len() /* smp_mb() */ /* smp_rmb() */ off = LOAD fifo->in + off off = LOAD fifo->out + off /* memcpy */ /* memcpy */ /* smp_wmb() */ /* smp_mb() */ STORE fifo->in += off STORE fifo->out += off

两个函数的内存访问的会产生干扰的操作位于 kfifo_len() 中,假设现在是单生产者单消费者模式,考虑下面的情况

        kfifo_in()
t1 out = LOAD fifo->out
t2 /* smp_rmb() */
t3 len = LOAD fifo->in - out
t4 /* smp_mb() */ kfifo_out()
t5 off = LOAD fifo->in + off out = LOAD fifo->out
t6 /* memcpy */ /* smp_rmb() */
t7 /* smp_wmb() */ len = LOAD fifo->in - out
t8 STORE fifo->in += off /* smp_rmb() */
t9 off = LOAD fifo->out + off
t10 /* memcpy */
t11 /* smp_mb() */
t12 STORE fifo->out += off kfifo_out()
t1 out = LOAD fifo->out
t2 /* smp_rmb() */
t3 len = LOAD fifo->in - out
t4 /* smp_rmb() */ kfifo_in()
t5 off = LOAD fifo->out + off out = LOAD fifo->out
t6 /* memcpy */ /* smp_rmb() */
t7 /* smp_mb() */ len = LOAD fifo->in - out
t8 STORE fifo->out += off /* smp_mb() */
t9 off = LOAD fifo->in + off
t10 /* memcpy */
t11 /* smp_wmb() */
t12 STORE fifo->in += off

后执行的函数在 t8 时刻,实际上内存已经写入或者读出,但是 in 和 out 并没有发生改变就被另外一个函数读取。
而这并不会产生错误,但是写入或者读出的数据都比实时的数据偏小,这也是 kfifo 的高明之处。
如果出队入队的操作特别频繁的话,对结果没影响。

若是要保持实时的顺序,即 t6 -> t8,一个函数的 memcpy 操作立刻对另一个 memcpy 可见,所以需要采取一些辅助措施来保证这个效果。

kfifo的更多相关文章

  1. 模仿Linux内核kfifo实现的循环缓存

    想实现个循环缓冲区(Circular Buffer),搜了些资料多数是基于循环队列的实现方式.使用一个变量存放缓冲区中的数据长度或者空出来一个空间来判断缓冲区是否满了.偶然间看到分析Linux内核的循 ...

  2. linux内核数据结构之kfifo

    1.前言 最近项目中用到一个环形缓冲区(ring buffer),代码是由linux内核的kfifo改过来的.缓冲区在文件系统中经常用到,通过缓冲区缓解cpu读写内存和读写磁盘的速度.例如一个进程A产 ...

  3. 内核ring buffer -- kfifo

    目前kernel的kfifo根据版本有两种形式, 早期的函数形式和现在的宏定义形式 1. 早期的(linux-3.0.56/kernel/kfifo.c) 感兴趣读者可以自己看, 源码如下: /* * ...

  4. linux内核数据结构之kfifo【转】

    1.前言 最近项目中用到一个环形缓冲区(ring buffer),代码是由linux内核的kfifo改过来的.缓冲区在文件系统中经常用到,通过缓冲区缓解cpu读写内存和读写磁盘的速度.例如一个进程A产 ...

  5. Linux内核数据结构之kfifo详解

    本文分析的原代码版本: 2.6.24.4 kfifo的定义文件: kernel/kfifo.c kfifo的头文件: include/linux/kfifo.h kfifo是内核里面的一个First ...

  6. STM32 & FreeRTOS & KFIFO (巧夺天工)

    巧夺天工 的 KFIFO ,用STM32实现. 实现源文件如下: /********************************************************** * * 文件名 ...

  7. 环形缓冲区-模仿linux kfifo【转】

    转自:https://blog.csdn.net/vertor11/article/details/53741681 struct kfifo{ uint8_t *buffer; uint32_t i ...

  8. Linux内核结构体--kfifo 环状缓冲区

    转载链接:http://blog.csdn.net/yusiguyuan/article/details/41985907 1.前言 最近项目中用到一个环形缓冲区(ring buffer),代码是由L ...

  9. Linux内核中的队列 kfifo【转】

    转自:http://airekans.github.io/c/2015/10/12/linux-kernel-data-structure-kfifo#api 在内核中经常会有需要用到队列来传递数据的 ...

  10. Linux kernel kfifo分析【转】

    转自:https://zohead.com/archives/linux-kernel-kfifo/ 本文同步自(如浏览不正常请点击跳转):https://zohead.com/archives/li ...

随机推荐

  1. Network出现两次相同请求?

    出现的状况 Network中出现了两个相同的请求(如图),两个发起了同样的请求,花的时间却不同,一个55ms,一个花了294ms.   两个相同的请求 什么情况啊?研究了一番,我发现有一个地方是不同的 ...

  2. golang 处理 json 结构体

    首先 我们来看一下这个json 字串 { "resp": { ", "respMsg": "成功", "app" ...

  3. 关于scrapy中如何区分是接着发起请求还是开始保存文件

    一.区分 根据yield迭代器生成的对象是request对象还是item对象 二.item 1.配置tem对象 在items.py文件中设置类 class MyscrapyItem(scrapy.It ...

  4. 由导入paramkio包失败,而pip list又能查到此包,而引出的:离线安装python第三方库的实用方法:解决公司内网,服务器/电脑不能上网却需要安装python三方库问题(下:Linux环境中)

    问题描述: 公司的Linux服务器是内网,今天要实现某个功能,会用到python控制ssh,需要安装一个Paramkio库,和上一篇一样,仅仅依靠Pypi上下载下来的离线.whl安装包是不行的,lin ...

  5. MySQL学习——管理用户权限

    MySQL学习——管理用户权限 摘要:本文主要学习了使用DCL语句管理用户权限的方法. 了解用户权限 什么是用户 用户,指的就是操作和使用MySQL数据库的人.使用MySQL数据库需要用户先通过用户名 ...

  6. SQL语句添加表外键

    ALTER TABLE 表名 ADD CONSTRAINT FK_ID FOREIGN KEY(外键列) REFERENCES 外键表(外键表主键)

  7. dd 工具使用; SSD 顺序写性能测试;

    dd 工具使用: dd 也是我们经常使用到的磁盘测试工具,Linux服务器装好系统之后,想要知道硬盘的读写是否能满足服务的需要,如果不满足硬盘的IO就是服务的一个瓶颈.我们可以使用dd命令简单进行测试 ...

  8. 对java的几点个人浅浅的认知

    特点   简单地说,Java 具有如下特点:简单的.面向对象.平台无关.多线程.分布式.安全. 高性能.可靠的.解释型.自动垃圾回收等特点. 主要面向internet的语言 Java比其他任何一门语言 ...

  9. 01-Node.js学习笔记-模块成员的导出导入

    什么是Node.js Node.js是一个让javascript运行在服务端的开发平台: Node.js能做什么? 1.基于社交网络的大规模web应用: 2.命令行工具 3.交互式终端程序 4.带有图 ...

  10. python(leetcode)498. 对角线遍历

    这题难度中等,记录下思路 第一个会超时, 第二个:思想是按斜对角线行进行右下左上交替遍历, def traverse(matrix): n=len(matrix)-1 m=len(matrix[0]) ...