kfifo
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的更多相关文章
- 模仿Linux内核kfifo实现的循环缓存
想实现个循环缓冲区(Circular Buffer),搜了些资料多数是基于循环队列的实现方式.使用一个变量存放缓冲区中的数据长度或者空出来一个空间来判断缓冲区是否满了.偶然间看到分析Linux内核的循 ...
- linux内核数据结构之kfifo
1.前言 最近项目中用到一个环形缓冲区(ring buffer),代码是由linux内核的kfifo改过来的.缓冲区在文件系统中经常用到,通过缓冲区缓解cpu读写内存和读写磁盘的速度.例如一个进程A产 ...
- 内核ring buffer -- kfifo
目前kernel的kfifo根据版本有两种形式, 早期的函数形式和现在的宏定义形式 1. 早期的(linux-3.0.56/kernel/kfifo.c) 感兴趣读者可以自己看, 源码如下: /* * ...
- linux内核数据结构之kfifo【转】
1.前言 最近项目中用到一个环形缓冲区(ring buffer),代码是由linux内核的kfifo改过来的.缓冲区在文件系统中经常用到,通过缓冲区缓解cpu读写内存和读写磁盘的速度.例如一个进程A产 ...
- Linux内核数据结构之kfifo详解
本文分析的原代码版本: 2.6.24.4 kfifo的定义文件: kernel/kfifo.c kfifo的头文件: include/linux/kfifo.h kfifo是内核里面的一个First ...
- STM32 & FreeRTOS & KFIFO (巧夺天工)
巧夺天工 的 KFIFO ,用STM32实现. 实现源文件如下: /********************************************************** * * 文件名 ...
- 环形缓冲区-模仿linux kfifo【转】
转自:https://blog.csdn.net/vertor11/article/details/53741681 struct kfifo{ uint8_t *buffer; uint32_t i ...
- Linux内核结构体--kfifo 环状缓冲区
转载链接:http://blog.csdn.net/yusiguyuan/article/details/41985907 1.前言 最近项目中用到一个环形缓冲区(ring buffer),代码是由L ...
- Linux内核中的队列 kfifo【转】
转自:http://airekans.github.io/c/2015/10/12/linux-kernel-data-structure-kfifo#api 在内核中经常会有需要用到队列来传递数据的 ...
- Linux kernel kfifo分析【转】
转自:https://zohead.com/archives/linux-kernel-kfifo/ 本文同步自(如浏览不正常请点击跳转):https://zohead.com/archives/li ...
随机推荐
- Think in Java 笔记(chapter1-7)
Content Chapter 1:对象导论 Chapter 2:一切都是对象 Chapter 3:操作符 Chapter 4:控制执行流程 Chapter 5:初始化与清理 Chapter 6:访问 ...
- Python:requests库、BeautifulSoup4库的基本使用(实现简单的网络爬虫)
Python:requests库.BeautifulSoup4库的基本使用(实现简单的网络爬虫) 一.requests库的基本使用 requests是python语言编写的简单易用的HTTP库,使用起 ...
- [译]Vulkan教程(02)概况
[译]Vulkan教程(02)概况 这是我翻译(https://vulkan-tutorial.com)上的Vulkan教程的第2篇. This chapter will start off with ...
- leetcode-數組篇
Remove Element public class Lc27 { public static int removeElement(int[] nums, int val) { if (nums = ...
- go语言的错误处理
1.系统自己抛异常 //go语言抛异常 func test3_1() { l := [5] int {0,1,2,3,4} var index int = 6 fmt.Println(l) l[ind ...
- 【带着canvas去流浪(10)】文字烟花
目录 一. 文字烟花 二. 动画原理 2.1 像素操作 2.2 烟花生成算法 2.3 计时器 示例代码托管在:http://www.github.com/dashnowords/blogs 博客园地址 ...
- python爬虫公众号所有信息,并批量下载公众号视频
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 数据分析实战 PS:如有需要Python学习资料的小伙伴可以加点击 ...
- PHP中发送qq邮件
<?php namespace app\home\logic; use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\Except ...
- linux-创建/使用快照/克隆(类似windows中备份还原)
一. 创建/使用快照 1.什么是快照 说的直白一点,就是创建一个备份. 当执行了不可逆的错误操作后,可以通过快照用来恢复系统 2.创建快照的3种模式 挂载状态下创建快照 开机状态下创建 ...
- Eclipse:批量将Java源代码文件的编码从GBK转为UTF-8
很简单的几行代码,就可以批量将GBK格式的java文件转为UTF-8格式. 基本上所有文本文件的编码转换都可以采用这种方式. import java.io.File; import java.io.I ...