kfifo 用户空间实现

2023-11-22 20:58
文章标签 实现 用户 空间 kfifo

本文主要是介绍kfifo 用户空间实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

按照linux内核对kfifo的实现,修改成用户空间的kfifo,kfifo是一个循环存储队列,队列是一个大块内存,通过in和out指针管理进和出队列。比较适合大小固定的数据存储。这里的实现没有加锁机制!内核kfifo原理,参考http://blog.csdn.net/linyt/article/details/5764312

kfifo头文件。

#ifndef _Linux_KFIFO_H
#define _Linux_KFIFO_H#define __u32 unsigned long
#define __u64 unsigned long long#define min(x,y) ((x) < (y) ? (x) : (y) )#define max(x,y) ((x) > (y) ? (x) : (y) )
/*
static inline int fls(int x)
{int r;__asm__("bsrl %1,%0nt""jnz 1fnt""movl $-1,%0n""1:" : "=r" (r) : "rm" (x));return r+1;
}*/
static inline int fls(int x)
{int r = 32; if (!x)return 0;if (!(x & 0xffff0000u)) {x <<= 16; r -= 16; }   if (!(x & 0xff000000u)) {x <<= 8;r -= 8;}   if (!(x & 0xf0000000u)) {x <<= 4;r -= 4;}   if (!(x & 0xc0000000u)) {x <<= 2;r -= 2;}   if (!(x & 0x80000000u)) {x <<= 1;r -= 1;}   return r;
}static inline int fls64(__u64 x)
{__u32 h = x >> 32;if (h)return fls(h) + 32;return fls(x);
}static inline unsigned fls_long(unsigned long l)
{if (sizeof(l) == 4)return fls(l);return fls64(l);
}static inline unsigned long roundup_pow_of_two(unsigned long x)
{return 1UL << fls_long(x - 1);
}struct kfifo {unsigned char *buffer;    /* the buffer holding the data */unsigned int size;    /* the size of the allocated buffer */unsigned int in;    /* data is added at offset (in % size) */unsigned int out;    /* data is extracted from off. (out % size) */
};struct kfifo *kfifo_init(unsigned char *buffer, unsigned int size);
struct kfifo *kfifo_alloc(unsigned int size);
void kfifo_free(struct kfifo *fifo);
unsigned int __kfifo_put(struct kfifo *fifo, unsigned char *buffer, unsigned int len);
unsigned int __kfifo_get(struct kfifo *fifo, unsigned char *buffer, unsigned int len);static inline void __kfifo_reset(struct kfifo *fifo)
{fifo->in = fifo->out = 0;
}static inline void kfifo_reset(struct kfifo *fifo)
{__kfifo_reset(fifo);}static inline unsigned int kfifo_put(struct kfifo *fifo,unsigned char *buffer, unsigned int len)
{unsigned int ret;ret = __kfifo_put(fifo, buffer, len);return ret;
}static inline unsigned int kfifo_get(struct kfifo *fifo,unsigned char *buffer, unsigned int len)
{unsigned int ret;ret = __kfifo_get(fifo, buffer, len);if (fifo->in == fifo->out)fifo->in = fifo->out = 0;return ret;
}static inline unsigned int __kfifo_len(struct kfifo *fifo)
{return fifo->in - fifo->out;
}static inline unsigned int kfifo_len(struct kfifo *fifo)
{unsigned int ret;ret = __kfifo_len(fifo);return ret;
}#endif
kfifo实现

#include "kfifo.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct kfifo *kfifo_init(unsigned char *buffer, unsigned int size)
{struct kfifo *fifo;fifo = (struct kfifo *)malloc(sizeof(struct kfifo));if (!fifo)return NULL;fifo->buffer = buffer;fifo->size = size;fifo->in = fifo->out = 0;return fifo;
}struct kfifo *kfifo_alloc(unsigned int size)
{unsigned char *buffer;struct kfifo *ret;if (size & (size - 1)) {fprintf(stderr,"size > 0x80000000n");size = roundup_pow_of_two(size);}buffer = (unsigned char *)malloc(size);if (!buffer)return NULL;ret = kfifo_init(buffer, size);if ((unsigned long)ret <= 0){free(buffer);}return ret;
}void kfifo_free(struct kfifo *fifo)
{free(fifo->buffer);free(fifo);
}unsigned int __kfifo_put(struct kfifo *fifo, unsigned char *buffer, unsigned int len)
{unsigned int l;len = min(len, fifo->size - fifo->in + fifo->out);l = min(len, fifo->size - (fifo->in & (fifo->size - 1)));memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), buffer, l);memcpy(fifo->buffer, buffer + l, len - l);fifo->in += len;return len;
}unsigned int __kfifo_get(struct kfifo *fifo,unsigned char *buffer, unsigned int len)
{unsigned int l;len = min(len, fifo->in - fifo->out);l = min(len, fifo->size - (fifo->out & (fifo->size - 1)));memcpy(buffer, fifo->buffer + (fifo->out & (fifo->size - 1)), l);fifo->out += len;return len;
}

kfifo测试(来自网友的代码)
#define FIFO_LENGTH 4096
#include <stdio.h>
#include <pthread.h>
#include <strings.h>
#include <string.h>
#include "kfifo.h"
struct ll_param
{struct kfifo * fifo;int msg_len;
};static struct ll_param fifo;void thread_reader(void * param)
{int read_len=0;unsigned int counter=0;unsigned char buffer[FIFO_LENGTH];struct ll_param * p=(struct ll_param *)param;printf("nnn = %d\n", roundup_pow_of_two(5));    for(;;){bzero(buffer, FIFO_LENGTH);read_len=kfifo_get(p->fifo, buffer, 25);if(read_len !=0 ){printf("Read len:%d, buffer is  :< %s >n\n", read_len, buffer);}else{counter++;}if(counter > 20){break;}usleep(50000);}
}void thread_writer(void * param)
{unsigned int write_len = 0;unsigned int counter = 0;unsigned char buffer[32];struct ll_param * p = (struct ll_param *)param;for(counter = 0; counter < 100; counter++){bzero(buffer,32);sprintf((char *)buffer, "This is %d message.n", counter);write_len=kfifo_put(p->fifo, buffer, 25); //strlen((char *)buffer)usleep(100);}
}int main(void)
{pthread_t pidr;pthread_t pidw;fifo.msg_len = 10;fifo.fifo = kfifo_alloc(FIFO_LENGTH);pthread_create(&pidw, NULL, (void *)thread_writer, &fifo);pthread_create(&pidr, NULL, (void *)thread_reader, &fifo);pthread_join(pidr, NULL);pthread_join(pidw, NULL);kfifo_free(fifo.fifo);printf("nGoodbye!n\n");return 0;
}

Makefile

CFLAGS = -O2  -Wall 
INCLUDE = -I /
CC =  gcc test:test.o  kfifo.o${CC} ${CFLAGS} test.o  kfifo.o -o $@ ${INCLUDE} -pthreadtest.o:$(CC) -c test.c ${INCLUDE} -pthread
kfifo.o:$(CC) -c kfifo.c ${INCLUDE}
clean:rm -rf *.o test


这篇关于kfifo 用户空间实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/412867

相关文章

SpringBoot集成EasyPoi实现Excel模板导出成PDF文件

《SpringBoot集成EasyPoi实现Excel模板导出成PDF文件》在日常工作中,我们经常需要将数据导出成Excel表格或PDF文件,本文将介绍如何在SpringBoot项目中集成EasyPo... 目录前言摘要简介源代码解析应用场景案例优缺点分析类代码方法介绍测试用例小结前言在日常工作中,我们经

基于Python实现简易视频剪辑工具

《基于Python实现简易视频剪辑工具》这篇文章主要为大家详细介绍了如何用Python打造一个功能完备的简易视频剪辑工具,包括视频文件导入与格式转换,基础剪辑操作,音频处理等功能,感兴趣的小伙伴可以了... 目录一、技术选型与环境搭建二、核心功能模块实现1. 视频基础操作2. 音频处理3. 特效与转场三、高

Python实现中文文本处理与分析程序的示例详解

《Python实现中文文本处理与分析程序的示例详解》在当今信息爆炸的时代,文本数据的处理与分析成为了数据科学领域的重要课题,本文将使用Python开发一款基于Python的中文文本处理与分析程序,希望... 目录一、程序概述二、主要功能解析2.1 文件操作2.2 基础分析2.3 高级分析2.4 可视化2.5

Java实现预览与打印功能详解

《Java实现预览与打印功能详解》在Java中,打印功能主要依赖java.awt.print包,该包提供了与打印相关的一些关键类,比如PrinterJob和PageFormat,它们构成... 目录Java 打印系统概述打印预览与设置使用 PageFormat 和 PrinterJob 类设置页面格式与纸张

使用Go实现文件复制的完整流程

《使用Go实现文件复制的完整流程》本案例将实现一个实用的文件操作工具:将一个文件的内容完整复制到另一个文件中,这是文件处理中的常见任务,比如配置文件备份、日志迁移、用户上传文件转存等,文中通过代码示例... 目录案例说明涉及China编程知识点示例代码代码解析示例运行练习扩展小结案例说明我们将通过标准库 os

Python实现终端清屏的几种方式详解

《Python实现终端清屏的几种方式详解》在使用Python进行终端交互式编程时,我们经常需要清空当前终端屏幕的内容,本文为大家整理了几种常见的实现方法,有需要的小伙伴可以参考下... 目录方法一:使用 `os` 模块调用系统命令方法二:使用 `subprocess` 模块执行命令方法三:打印多个换行符模拟

SpringBoot+EasyPOI轻松实现Excel和Word导出PDF

《SpringBoot+EasyPOI轻松实现Excel和Word导出PDF》在企业级开发中,将Excel和Word文档导出为PDF是常见需求,本文将结合​​EasyPOI和​​Aspose系列工具实... 目录一、环境准备与依赖配置1.1 方案选型1.2 依赖配置(商业库方案)二、Excel 导出 PDF

Python实现MQTT通信的示例代码

《Python实现MQTT通信的示例代码》本文主要介绍了Python实现MQTT通信的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 安装paho-mqtt库‌2. 搭建MQTT代理服务器(Broker)‌‌3. pytho

使用zip4j实现Java中的ZIP文件加密压缩的操作方法

《使用zip4j实现Java中的ZIP文件加密压缩的操作方法》本文介绍如何通过Maven集成zip4j1.3.2库创建带密码保护的ZIP文件,涵盖依赖配置、代码示例及加密原理,确保数据安全性,感兴趣的... 目录1. zip4j库介绍和版本1.1 zip4j库概述1.2 zip4j的版本演变1.3 zip4

python生成随机唯一id的几种实现方法

《python生成随机唯一id的几种实现方法》在Python中生成随机唯一ID有多种方法,根据不同的需求场景可以选择最适合的方案,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习... 目录方法 1:使用 UUID 模块(推荐)方法 2:使用 Secrets 模块(安全敏感场景)方法