我是靠谱客的博主 幸福小松鼠,最近开发中收集的这篇文章主要介绍linux内核循环队列,循环队列-队列的顺序表示和实现3(linux内核实现),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

/******************************************************************************/

// 循环队列-队列的顺序表示和实现3(linux内核实现)

/******************************************************************************/

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) */

spinlock_t *lock;          /* protects concurrent modifications */

};

struct kfifo *kfifo_init(unsigned char *buffer, unsigned int size,

gfp_t gfp_mask, spinlock_t *lock)

{

struct kfifo *fifo;

/* size must be a power of 2 */

BUG_ON(!is_power_of_2(size));

fifo = kmalloc(sizeof(struct kfifo), gfp_mask);

if (!fifo)

return ERR_PTR(-ENOMEM);

fifo->buffer = buffer;

fifo->size = size;

fifo->in = fifo->out = 0;

fifo->lock = lock;

return fifo;

}

struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock)

{

unsigned char *buffer;

struct kfifo *ret;

if (!is_power_of_2(size)) {

BUG_ON(size > 0x80000000);

size = roundup_pow_of_two(size);

}

buffer = kmalloc(size, gfp_mask);

if (!buffer)

return ERR_PTR(-ENOMEM);

ret = kfifo_init(buffer, size, gfp_mask, lock);

if (IS_ERR(ret))

kfree(buffer);

return ret;

}

struct kfifo *kfifo_init(unsigned char *buffer, unsigned int size,

gfp_t gfp_mask, spinlock_t *lock)

{

struct kfifo *fifo;

/* size must be a power of 2 */

BUG_ON(!is_power_of_2(size));

fifo = kmalloc(sizeof(struct kfifo), gfp_mask);

if (!fifo)

return ERR_PTR(-ENOMEM);

fifo->buffer = buffer;

fifo->size = size;

fifo->in = fifo->out = 0;

fifo->lock = lock;

return fifo;

}

struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock)

{

unsigned char *buffer;

struct kfifo *ret;

if (!is_power_of_2(size)) {

BUG_ON(size > 0x80000000);

size = roundup_pow_of_two(size);

}

buffer = kmalloc(size, gfp_mask);

if (!buffer)

return ERR_PTR(-ENOMEM);

ret = kfifo_init(buffer, size, gfp_mask, lock);

if (IS_ERR(ret))

kfree(buffer);

return ret;

}

static inline unsigned int kfifo_put(struct kfifo *fifo,

const unsigned char *buffer, unsigned int len)

{

unsigned long flags;

unsigned int ret;

spin_lock_irqsave(fifo->lock, flags);

ret = __kfifo_put(fifo, buffer, len);

spin_unlock_irqrestore(fifo->lock, flags);

return ret;

}

static inline unsigned int kfifo_get(struct kfifo *fifo,

unsigned char *buffer, unsigned int len)

{

unsigned long flags;

unsigned int ret;

spin_lock_irqsave(fifo->lock, flags);

ret = __kfifo_get(fifo, buffer, len);

//当fifo->in == fifo->out时,buffer为空

if (fifo->in == fifo->out)

fifo->in = fifo->out = 0;

spin_unlock_irqrestore(fifo->lock, flags);

return ret;

}

unsigned int __kfifo_put(struct kfifo *fifo,

const unsigned char *buffer, unsigned int len)

{

unsigned int l;

len = min(len, fifo->size - fifo->in + fifo->out);

/*

* Ensure that we sample the fifo->out index -before- we

* start putting bytes into the kfifo.

*/

smp_mb();

/* first put the data starting from fifo->in to buffer end */

l = min(len, fifo->size - (fifo->in & (fifo->size - 1)));

memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), buffer, l);

/* then put the rest (if any) at the beginning of the buffer */

memcpy(fifo->buffer, buffer + l, len - l);

/*

* Ensure that we add the bytes to the kfifo -before-

* we update the fifo->in index.

*/

smp_wmb();

fifo->in += len;  //每次累加,到达最大值后溢出,自动转为0

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

/*

* Ensure that we sample the fifo->in index -before- we

* start removing bytes from the kfifo.

*/

smp_rmb();

/* first get the data from fifo->out until the end of the buffer */

l = min(len, fifo->size - (fifo->out & (fifo->size - 1)));

memcpy(buffer, fifo->buffer + (fifo->out & (fifo->size - 1)), l);

/* then get the rest (if any) from the beginning of the buffer */

memcpy(buffer + l, fifo->buffer, len - l);

/*

* Ensure that we remove the bytes from the kfifo -before-

* we update the fifo->out index.

*/

smp_mb();

fifo->out += len; //每次累加,到达最大值后溢出,自动转为0

return len;

}

最后

以上就是幸福小松鼠为你收集整理的linux内核循环队列,循环队列-队列的顺序表示和实现3(linux内核实现)的全部内容,希望文章能够帮你解决linux内核循环队列,循环队列-队列的顺序表示和实现3(linux内核实现)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(51)

评论列表共有 0 条评论

立即
投稿
返回
顶部