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);
}