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

相关文章

openCV中KNN算法的实现

《openCV中KNN算法的实现》KNN算法是一种简单且常用的分类算法,本文主要介绍了openCV中KNN算法的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录KNN算法流程使用OpenCV实现KNNOpenCV 是一个开源的跨平台计算机视觉库,它提供了各

OpenCV图像形态学的实现

《OpenCV图像形态学的实现》本文主要介绍了OpenCV图像形态学的实现,包括腐蚀、膨胀、开运算、闭运算、梯度运算、顶帽运算和黑帽运算,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起... 目录一、图像形态学简介二、腐蚀(Erosion)1. 原理2. OpenCV 实现三、膨胀China编程(

通过Spring层面进行事务回滚的实现

《通过Spring层面进行事务回滚的实现》本文主要介绍了通过Spring层面进行事务回滚的实现,包括声明式事务和编程式事务,具有一定的参考价值,感兴趣的可以了解一下... 目录声明式事务回滚:1. 基础注解配置2. 指定回滚异常类型3. ​不回滚特殊场景编程式事务回滚:1. ​使用 TransactionT

Android实现打开本地pdf文件的两种方式

《Android实现打开本地pdf文件的两种方式》在现代应用中,PDF格式因其跨平台、稳定性好、展示内容一致等特点,在Android平台上,如何高效地打开本地PDF文件,不仅关系到用户体验,也直接影响... 目录一、项目概述二、相关知识2.1 PDF文件基本概述2.2 android 文件访问与存储权限2.

使用Python实现全能手机虚拟键盘的示例代码

《使用Python实现全能手机虚拟键盘的示例代码》在数字化办公时代,你是否遇到过这样的场景:会议室投影电脑突然键盘失灵、躺在沙发上想远程控制书房电脑、或者需要给长辈远程协助操作?今天我要分享的Pyth... 目录一、项目概述:不止于键盘的远程控制方案1.1 创新价值1.2 技术栈全景二、需求实现步骤一、需求

Spring Shell 命令行实现交互式Shell应用开发

《SpringShell命令行实现交互式Shell应用开发》本文主要介绍了SpringShell命令行实现交互式Shell应用开发,能够帮助开发者快速构建功能丰富的命令行应用程序,具有一定的参考价... 目录引言一、Spring Shell概述二、创建命令类三、命令参数处理四、命令分组与帮助系统五、自定义S

SpringBatch数据写入实现

《SpringBatch数据写入实现》SpringBatch通过ItemWriter接口及其丰富的实现,提供了强大的数据写入能力,本文主要介绍了SpringBatch数据写入实现,具有一定的参考价值,... 目录python引言一、ItemWriter核心概念二、数据库写入实现三、文件写入实现四、多目标写入

Android Studio 配置国内镜像源的实现步骤

《AndroidStudio配置国内镜像源的实现步骤》本文主要介绍了AndroidStudio配置国内镜像源的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,... 目录一、修改 hosts,解决 SDK 下载失败的问题二、修改 gradle 地址,解决 gradle

SpringSecurity JWT基于令牌的无状态认证实现

《SpringSecurityJWT基于令牌的无状态认证实现》SpringSecurity中实现基于JWT的无状态认证是一种常见的做法,本文就来介绍一下SpringSecurityJWT基于令牌的无... 目录引言一、JWT基本原理与结构二、Spring Security JWT依赖配置三、JWT令牌生成与

SpringBoot实现微信小程序支付功能

《SpringBoot实现微信小程序支付功能》小程序支付功能已成为众多应用的核心需求之一,本文主要介绍了SpringBoot实现微信小程序支付功能,文中通过示例代码介绍的非常详细,对大家的学习或者工作... 目录一、引言二、准备工作(一)微信支付商户平台配置(二)Spring Boot项目搭建(三)配置文件