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. 阿里云 centOS系统 配置 node + ngnix

    **centOS系统可以直接使用yun命令** 安装node 1.使用git将源码克隆到本地的~/.nvm目录下,并检查最新版本.> yum install git > git clone ...

  2. GitLab CI/CD持续集成设置

    GitLab CI/CD持续设置 官方文档地址(https://docs.gitlab.com/ee/ci/README.html) GitLab CI.CD功能非常完善,只需要简单几步,就可以完成项 ...

  3. SpringBoot2.0 基础案例(15):配置MongoDB数据库,实现增删改查逻辑

    本文源码:GitHub·点这里 || GitEE·点这里 一.NoSQL简介 1.NoSQL 概念 NoSQL( Not Only SQL ),意即"不仅仅是SQL".对不同于传统 ...

  4. MFC图形编辑界面工具

    一.背景 喔,五天的实训终于结束了,学校安排的这次实训课名称叫高级程序设计实训,但在我看来,主要是学习了Visual C++ .NET所提供的MFC(Microsoft Foundation Clas ...

  5. 前端之HTML介绍及使用

    一.HTML介绍 1.1 web本质 在pycharm写入一下代码,然后在浏览器地址栏输入地址和端口127.0.0.1:8080,回车,回来运行代码,直接访问客户端发送的内容conn.send(b'& ...

  6. windows下cocos2d-x工程结构讲解

    这是我们新建好的工程,稍微解释一下我们开发windows的cocos应用所用到的几个文件夹的作用 Classes文件夹,存放游戏代码中的类的源码,当然我们放在别的地方也可以,只要配置好依赖关系就行了 ...

  7. C#深入浅出之数据类型

    基本数据类型        C#支持完整的BCL(基类库)名字,但是最好都统一使用关键字进行使用与开发,比如使用int而不是System.Int32,以及使用string类型时候应当使用string而 ...

  8. C#中获取指定路径下指定后缀名的所有文件的路径的list

    场景 指定一个路径和后缀名,查找这个路径下所有以此后缀名结尾的文件. 注: 博客主页: https://blog.csdn.net/badao_liumang_qizhi关注公众号 霸道的程序猿 获取 ...

  9. HTTP中的Accept-Encoding、Content-Encoding、Transfer-Encoding、Content-Type

    Accept-Encoding和Content-Encoding Accept-Encoding和Content-Encoding是HTTP中用来对采用何种压缩格式传输正文进行协定的一对header. ...

  10. 从系统学Android--2.5Activity启动模式

    本系列文章目录:更多精品文章分类 本系列持续更新中.... Activity 的启动模式一共有四种,分别是:standard.singleTop.singleTask.singleInstance . ...