Я изучаю реализацию kfifo.c в ядре Linux версии 2.6. Я не совсем понимаю, как указатели входа и выхода очереди обрабатывают оставшуюся часть.
Например, kfifo.c использует l = fifo->in - fifo->out для расчета пространства, используемого в очереди. Предположим, in = 0, out = 1, fifo->size = 8. И in, и out представляют собой беззнаковые целые числа, оба 32-битные. Таким образом, l = fifo->in - fifo->out будет 32 бита, 1 представляет собой 4294967295. Но фактически используемое пространство в очереди равно l = (fifo->in - fifo->out) & (fifo-> size-1) = 7
Итак, моя проблема: почему l не делает И с fifo->size-1?
unsigned int __kfifo_out_peek(struct __kfifo *fifo,
void *buf, unsigned int len)
{
unsigned int l;
l = fifo->in - fifo->out;
if (len > l)
len = l;
kfifo_copy_out(fifo, buf, len, fifo->out);
return len;
}
static void kfifo_copy_out(struct __kfifo *fifo, void *dst,
unsigned int len, unsigned int off)
{
unsigned int size = fifo->mask + 1;
unsigned int esize = fifo->esize;
unsigned int l;
off &= fifo->mask;
if (esize != 1) {
off *= esize;
size *= esize;
len *= esize;
}
l = min(len, size - off);
memcpy(dst, fifo->data + off, l);
memcpy(dst + l, fifo->data, len - l);
/*
* make sure that the data is copied before
* incrementing the fifo->out index counter
*/
smp_wmb();
}
Кроме того, у меня есть еще один вопрос: реализация kfifo_unused в kfifo.c. fifo->mask+1 представляет fifo->размер. Также предполагается, что вход = 0, выход = 1, fifo->size = 8. Следующий код вернет 9, но на самом деле используемое пространство должно быть 1.
static inline unsigned int kfifo_unused(struct __kfifo *fifo)
{
return (fifo->mask + 1) - (fifo->in - fifo->out);
}
Подробнее здесь: https://stackoverflow.com/questions/792 ... nux-kernel
Проблема переноса целых чисел в kfifo.c в ядре Linux ⇐ Linux
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Зачем kfifo нужен smp_wmb даже при наличии spin_lock_irqsave в ядре версии 4.9.37
Anonymous » » в форуме Linux - 0 Ответы
- 15 Просмотры
-
Последнее сообщение Anonymous
-