ring buffer 实现机制

本文介绍了Ring Buffer的实现机制,这是一种循环使用的数据结构。首先,我们定义了ringbuffer的数据结构,接着阐述了其初始化过程,最后详细讲解了ringbuffer的读取操作。通过这篇文章,读者将能深入理解ringbuffer如何在数据传输中有效地管理内存。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Ring buffer是一种环状buffer, 读写完一遍之后,又从头开始读写。

1. ringbuffer定义如下:

struct OutRingBuffer
{
    char *buffer;        // 数据存储区
    int wr_pointer;      // 写指针
    int rd_pointer;      // 读指针
    int data_size;       // buffer size
    int size;            // rb size
};

//下面是一些操作函数,如初始化,读,写,清0等
/* ring buffer functions */
int rb_init (struct OutRingBuffer **, int);
void rb_destroy (struct OutRingBuffer *);
int rb_write (struct OutRingBuffer *, unsigned char *, int);
int rb_free (struct OutRingBuffer *);
int rb_read (struct OutRingBuffer *, unsigned char *, int);

int rb_data_size (struct OutRingBuffer *);
int rb_clear (struct OutRingBuffer *);

2. ringbuffer 初始化:

/* call before output thread is active !!!!! */
int rb_init (struct OutRingBuffer **rb, int size)
{
	struct OutRingBuffer *ring;

	if(rb==NULL || size < 1024)
	{
		return -EINVAL;
	}
	//alloc and memset OutRingBuffer
	ring = kzalloc (sizeof (struct OutRingBuffer), GFP_KERNEL);
	if(ring == NULL)
	{
		return -ENOMEM;
	}

	ring->size = 1;
	while(ring->size < size)
		ring->size <<= 1;  //size = 1, 2, 4, 8, 16... (2的指数倍)

	//alloc ring->buffer, size = ring->size
	ring->buffer=kmalloc(sizeof(char)*(ring->size), GFP_KERNEL);
 
	if(ring->buffer == NULL)
	{
		kfree(ring);
		return -ENOMEM;
	}
   
	*rb = ring;  //用来返回分配的rb地址

	return 0;
}

3. ringbuffer 读操作:

int
rb_read (struct OutRingBuffer *rb, unsigned char * buf, int max)
{
	int total;
	int i;
	/* total = max = min(used, len) */
	total = rb_data_size(rb);

	if(max > total)
		max = total;
	else
		total = max;

	i = rb->rd_pointer;
	if(i + max > rb->size)
	{
                //先把剩余的rb->buffer 读完
		memcpy(buf, rb->buffer + i, rb->size - i);
		buf += rb->size - i;
		max -= rb->size - i;
		rb->data_size -= rb->size - i;
		i = 0;
	}

        //这里实现环状读写,读完了一个rb->buffer之后,又从头开始读入数据,从而实现回环。
	memcpy(buf, rb->buffer + i, max);
	rb->rd_pointer = i + max;
	rb->data_size -= max;
	return total;

}
int
rb_data_size (struct OutRingBuffer *rb)
{
	return rb->data_size;
}
4.  ringbuffer 写操作

/*
 * len --- the size you want to write into RB
 * buf --- the buffer you want to write into RB
 * rb --- the OutRingBuffer you want to write into
*/
int rb_write (struct OutRingBuffer *rb, unsigned char * buf, int len)
{
	int total;
	int i;

	//total = rb space left
	total = rb_free(rb);

	/* total = len =min(space, len) */
	if(len > total)
		len = total;
	else
		total = len;

	i = rb->wr_pointer;

        //如果数据长度超过了rb->size
	if(i + len > rb->size)
	{
                //从rb->wr_pointer 位置开始写入新数据,写入大小是rb剩下的部分
		memcpy(rb->buffer + i, buf, rb->size - i);
                //计算新buf地址,以后写入有用
		buf += rb->size - i;
                //计算需要写入的剩余长度
		len -= rb->size - i; 
                //计算写入后新的buffer大小
		rb->data_size += rb->size - i;
		i = 0;
	}
        //环状buffer就是这里实现的,这里从头开始写入数据,实现回环。
	memcpy(rb->buffer + i, buf, len);
        //写入新的wr_p
	rb->wr_pointer = i + len;
        //写入新的buffer size
	rb->data_size += len;
	return total;
}

int rb_free (struct OutRingBuffer *rb)
{
	return (rb->size - rb->data_size);  //计算本次写操作rb剩余空间
}

5. ringbuffer 清0 操作
int
rb_clear (struct OutRingBuffer *rb)
{
	memset(rb->buffer,0,rb->size);
	rb->rd_pointer=0;
	rb->wr_pointer=0;
	rb->data_size=0;
	return 0;
}
6. ringbuffer 注销:

void rb_destroy (struct OutRingBuffer *rb)
{
	kfree(rb->buffer);
	kfree(rb);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值