小言_互联网的博客

无锁环形缓冲区队列 kfifo

385人阅读  评论(0)

kfifo的移植

两个月前,我花了两天时间,查找Linux内核里kfifo的相关资料,将其从内核层移植到应用层,并成功应用于多线程CAN总线采集程序(一个线程接收/一个线程输出)。kfifo.c是从Linux 5.3 stable内核代码里复制出来的,路径是lib/kfifo,对应的kfifo.h路径是include/linux/kfifo.h。由于kfifo是内核里的代码,应用层无法直接使用,我做了如下修改:

  • 注释掉无关的或不必要的代码,如对内核头文件的引用,如涉及dma、sgl的代码

  • 重新实现某些功能,如采用SO上的代码取代了roundup_pow_of_two,用GCC内置函数__sync_synchronize取代了smp_wmb,重新定义了ARRAY_SIZE

代码仓库:https://github.com/liigo/kfifo

kfifo的使用

很简单就三点:用 DEFINE_KFIFO 定义缓冲区变量并初始化,用 kfifo_in 向缓冲区内写入数据,用 kfifo_out 从缓冲区取出数据。DEFINE_KFIFO宏参数1是一个变量名(调用者只给一个名称,宏内部负责定义类型和变量),参数2是自定义结构体(也可以是任意其他类型),参数3是缓冲区长度(必须是2的幂,单位是参数2的类型尺寸)。

DEFINE_KFIFO(g_canbuf, buf_item_t, 1024);
kfifo_in(&g_canbuf, &bufitem, 1);
int n = kfifo_out(&g_canbuf, &bufitem, 1);

kfifo代码里大量使用宏,理解起来很费劲,主要因为宏参数的类型不明确。


转载:https://blog.csdn.net/liigo/article/details/100993236
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场