7.11 Linux内核中的队列:KFIFO(上)
基本概念
内核版本:Linux-4.4.x
定义:lib/ kfifo.c include/ linux /kfifo.h
KFIFO基本操作
入队
初始化:kfifo_init \ kfifo_alloc
Kfifo_put
Kfifo_in \ kfifo_in_spinlocked
出队
Kfifo_get
Kfifo_out
数据结构
struct __kfifo {
unsigned int in;
unsigned int out;
unsigned int mask;
unsigned int esize; //每个元素的大小,2的幂
void *data;
};
kfifo_alloc
kififo.h
#define kfifo_alloc(fifo, size, gfp_mask) \
__kfifo_int_must_check_helper( \
({ \
typeof((fifo) + 1) __tmp = (fifo); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
__is_kfifo_ptr(__tmp) ? \
//前面都是做一些兼容,语句表达式直接看最后一行就行了
__kfifo_alloc(__kfifo, size, sizeof(*__tmp->type), gfp_mask) : \
-EINVAL; \
}) \
__kfifo_alloc
kififo.c
int __kfifo_alloc(struct __kfifo *fifo, unsigned int size,
size_t esize, gfp_t gfp_mask)
{
/*
* round down to the next power of 2, since our 'let the indices
* wrap' technique works only in this case.
*/
size = roundup_pow_of_two(size);
fifo->in = 0;
fifo->out = 0;
fifo->esize = esize;
if (size < 2) {
fifo->data = NULL;
fifo->mask = 0;
return -EINVAL;
}
fifo->data = kmalloc(size * esize, gfp_mask);
// data指向申请的堆空间
//size元素的个数
//esize 每个元素的大小
//gfp_mask = size-1
if (!fifo->data) {
fifo->mask = 0;
return -ENOMEM;
}
fifo->mask = size - 1;
return 0;
}