gpt4 book ai didi

c - 为什么kfifo在某些博客中是Circular queue

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:33:35 24 4
gpt4 key购买 nike

kfifo是Circlar队列吗?

在 Circlar 队列 WIKI ( https://en.wikipedia.org/wiki/Circular_buffer ) 中说“它是端到端连接的。”。但在 linux-4.16.12\lib\kfifo.c

int __kfifo_init(struct __kfifo *fifo, void *buffer,
unsigned int size, size_t esize)
{
size /= esize;

size = roundup_pow_of_two(size);

fifo->in = 0;
fifo->out = 0;
fifo->esize = esize;
fifo->data = buffer;

if (size < 2) {
fifo->mask = 0;
return -EINVAL;
}
fifo->mask = size - 1;

return 0;
}

我没有找到指向结束指针的开始指针,所以:

1) kfifo是Circlar队列吗?

2)如果是,如何证明?

最佳答案

Wikipedia page you mentioned指出循环缓冲区的行为就好像缓冲区是首尾相连的。实际上,循环缓冲区只是一个固定长度的数组,有两个索引指针(通常称为headtail,或者inout) 表示写入数据的“边界”。为了避免在缓冲区边界之外写入,对这些索引的所有算术运算都已完成 modulo缓冲区的长度。

通常,指针的含义是:

  • headin 索引,指示下一个可用的写入槽,以及
  • tailout 索引,表示最后读取(“删除”)的插槽。

还有两种边界状态:

  • 如果tail等于head,则缓冲区为空。
  • 如果增加 tail 模缓冲区长度会使 tailhead 相等,则缓冲区已满。

大多数实现将使用以下方法之一将索引保持在缓冲区范围内:

// check if index overflowed and reset
int fifo_increment_index(struct fifo *fifo, int index)
{
index = index + 1;
if (index > fifo->capacity)
index = 0;
return index;
}

// use the modulo operator (slower due to division,
// although it avoids branching)
int fifo_increment_index(struct fifo *fifo, int index)
{
index = (index + 1) % fifo->capacity; // modulo
return index;
}

// use a bitwise mask (in most cases the fastest approach),
// but works ONLY if capacity is a power of 2
int fifo_increment_index(struct fifo *fifo, int index)
{
// if capacity is 1024 (0x400), then
// mask will be 1023 (0x3FF)

index = (index + 1) & fifo->mask; // bitwise and
return index;
}

Linux kfifo 使用最后一种方法(按位掩码),这就是为什么它总是 ensures that the capacity is a power of two在 init 函数中 (size = roundup_pow_of_two(size))。

但是,它不会在索引发生变化时立即重置它们,而是在每次访问缓冲区时屏蔽它们:

#define __KFIFO_PEEK(data, out, mask) ( (data)[(out) & (mask)] )
#define __KFIFO_POKE(data, in, mask, val) ( (data)[(in) & (mask)] = (unsigned char)(val) )

对于 uint8_t 缓冲区,__KFIFO_PEEK 宏基本上是:

static inline uint8_t kfifo_peek(struct __kfifo *fifo)
{
int index = fifo->out & fifo->mask;
return fifo->data[index];
}

关于c - 为什么kfifo在某些博客中是Circular queue,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53476760/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com