修改自linux内核中的kfifo模块

6 篇文章 0 订阅

模块说明

这个模块是修改自linux kernel的fifo模块,我用在一些裸板程序上,作为基础的数据结构;
数据结构

struct __fifo {
	unsigned int	in;
	unsigned int	out;
	unsigned int	mask;
	unsigned int	esize;
	void		*data;
};

初始化函数

参数:
struct __fifo *fifo: 队列头
void *buffer:队列的buffer
unsigned int size:buffer的大小(字节)
size_t esize每个队列数据节点的大小(字节),比如每个队列的节点是个数据结构体,那这个值时结构体的大小

int fifo_init(struct __fifo *fifo, void *buffer,unsigned int size, size_t esize);

销毁函数

void  fifo_free(struct __fifo *fifo);

入队

unsigned int fifo_in(struct __fifo *fifo,	const void *buf, unsigned int len);

出队

unsigned int fifo_out(struct __fifo *fifo,void *buf, unsigned int len);

模块源码

H文件

#ifndef __BASEFIFO_H__
#define __BASEFIFO_H__

#include "myself_types.h"
#include <stdint.h>

struct __fifo {
	unsigned int	in;
	unsigned int	out;
	unsigned int	mask;
	unsigned int	esize;
	void		*data;
};



int fifo_init(struct __fifo *fifo, void *buffer,
		unsigned int size, size_t esize);

void  fifo_free(struct __fifo *fifo);

unsigned int fifo_in(struct __fifo *fifo,
		const void *buf, unsigned int len);

unsigned int fifo_out(struct __fifo *fifo,
		void *buf, unsigned int len);

#endif// __BASEFIFO_H__

C文件

#include "basefifo.h"

#include <stdlib.h>
#include <string.h>

	
#define EINVAL (1)

#define max(a, b) (a > b ? a : b )

#define min(a, b) (a < b ? a : b )


/*
	size 是buffer的大小,esize是fifo数据单元大小
*/
int fifo_init(struct __fifo *fifo, void *buffer,
		unsigned int size, size_t esize)
{
	/*得到队列深度*/
	size /= esize;
	/*这里缺少一个宏,需要将size向上扩展成2的幂,其实这里需要做强制判断,或者向下压缩成2的幂
	 *
	 */
	//size = roundup_pow_of_two(size);

	fifo->in = 0;
	fifo->out = 0;
	fifo->esize = esize;
	fifo->data = buffer;

	if (size < 2) {
		fifo->mask = 0;
		return -EINVAL;
	}
	fifo->mask = size - 1;
	return 0;
}

void  fifo_free(struct __fifo *fifo)
{
	//kfree(fifo->data);
	fifo->in = 0;
	fifo->out = 0;
	fifo->esize = 0;
	fifo->data = NULL;
	fifo->mask = 0;
}

STATIC INLINE unsigned int fifo_unused(struct __fifo *fifo)
{
	return (fifo->mask + 1) - (fifo->in - fifo->out);
}

static void fifo_copy_in(struct __fifo *fifo, const void *src,
		unsigned int len, unsigned int off)
{
	unsigned int size = fifo->mask + 1;
	unsigned int esize = fifo->esize;
	unsigned int l;

	off &= fifo->mask;
	if (esize != 1) {
		off *= esize;
		size *= esize;
		len *= esize;
	}
	l = min(len, size - off);

	/*! 必须类型强转,不然keil编译不过去 */
	memcpy((void*)((unsigned int)(fifo->data) + off), src, l);
	memcpy(fifo->data, (void*)((unsigned int)src + l), len - l);
	/*
	 * make sure that the data in the fifo is up to date before
	 * incrementing the fifo->in index counter
	 */
	//smp_wmb();
}

unsigned int fifo_in(struct __fifo *fifo,
		const void *buf, unsigned int len)
{
	unsigned int l;

	l = fifo_unused(fifo);
	if (len > l)
		len = l;

	fifo_copy_in(fifo, buf, len, fifo->in);
	fifo->in += len;
	return len;
}

static void fifo_copy_out(struct __fifo *fifo, void *dst,
		unsigned int len, unsigned int off)
{
	unsigned int size = fifo->mask + 1;
	unsigned int esize = fifo->esize;
	unsigned int l;

	off &= fifo->mask;
	if (esize != 1) {
		off *= esize;
		size *= esize;
		len *= esize;
	}
	l = min(len, size - off);
	/*! 必须类型强转,不然keil编译不过去 */
	memcpy(dst, (void *)((unsigned int)(fifo->data) + off), l);
	memcpy((void *)((unsigned int)dst + l), fifo->data, len - l);
	/*
	 * make sure that the data is copied before
	 * incrementing the fifo->out index counter
	 */
}

unsigned int fifo_out_peek(struct __fifo *fifo,
		void *buf, unsigned int len)
{
	unsigned int l;

	l = fifo->in - fifo->out;
	if (len > l)
		len = l;

	fifo_copy_out(fifo, buf, len, fifo->out);
	return len;
}

unsigned int fifo_out(struct __fifo *fifo,
		void *buf, unsigned int len)
{
	len = fifo_out_peek(fifo, buf, len);
	fifo->out += len;
	return len;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值