内核数据结构之队列

http://blog.csdn.net/fuyajun01/article/details/7413579

在操作系统内核中,一个常见的编程模式就是生产者和消费者。实现这种模式的最容易的方式就是队列。生产者将数据插入队列,消费者将数据移出队列。消费者以数据进队的顺序消费数据。

内核中通用队列的实现称为kfifo,其实现文件位于kernel/kfifo.c中。本部分讨论的API接口是基于2.6.33的。Linux的kfifo工作方式与其他队列一样,提供两个主要的操作:enqueue()和dequeue()。kfifo对象维护了两个偏移量:入口偏移量和出口偏移量。入口偏移量是下次进队发生的位置,出口偏移量是出队发生的位置。出口偏移量问题小于或等于入口偏移量。enqueue操作从入口偏移量处开始,将数据拷贝到队列中,操作完成后,入口偏移量相应的增加(拷进的数据长度)。dequeue操作从出口偏移量处开始,将数据拷贝出队列,操作完成后,出口偏移量相应地增加(拷出的数据长度)。

创建一个队列

int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask);

该函数创建和初始化一个大小为size字节的队列。

例子:

structkfifo fifo;

intret;

ret= kfifo_alloc(&kifo, PAGE_SIZE, GFP_KERNEL);

if(ret)

returnret;


自建队列函数

void kfifo_init(struct kfifo *fifo, void *buffer, unsigned int size);

静态定义一个队列

DECLARE_KFIFO(name,size);

INIT_KFIFO(name);

其中,队列的大小必须是2的指数。

入队

unsigned int kfifo_in(struct kfifo *fifo, const void *from, unsigned int len);

出队

unsigned int kfifo_out(struct kfifo *fifo, void *to, unsigned int len);

unsigned int kfifo_out_peek(struct kfifo *fifo, void *to, unsigned int len,

unsigned offset);

获取队列的大小

static inline unsigned int kfifo_size(struct kfifo *fifo);

该函数用于获取用于存储kfifo队列的缓冲区的总大小。

static inline unsigned int kfifo_len(struct kfifo *fifo);

该函数用于获取进入kfifo队列的字节数。

static inline unsigned int kfifo_avail(struct kfifo *fifo);

队列中可用于写入的剩余缓冲区的大小。

static inline int kfifo_is_empty(struct kfifo *fifo);

static inline int kfifo_is_full(struct kfifo *fifo);

上述两个函数分别用于判断队列是否为空或满。

重置和销毁队列

static inline void kfifo_reset(struct kfifo *fifo);

重置一个队列

void kfifo_free(struct kfifo *fifo);

释放一个kfifo,与kfifo_alloc()对应。

如果创建kfifo的时候使用的是kfifo_init()函数,那么提供相应的函数来释放缓冲区,而不是用kfifo_free()。

posted @ 2015-01-13 12:43  Merlin-magic  阅读(383)  评论(0编辑  收藏  举报