私は現在、Linuxキューの実装(kfifo)に関連する作業を進めています。
最近私は見つけた。存在する内の変数構造__kfifo継続的に増加し、使用する前にマスクとビット単位のANDを実行するだけで簡単に使用できます。ただし、キューイング関数(__kfifo_in)はオーバーフロー関連の問題を処理していないようです。__kfifo.in。私はこれがいくつかの問題を引き起こす可能性があると思います。__kfifo.outより大きい__kfifo.in。例えば、kfifo_lenマクロの使用法__tmpl->kfifo.in - __tmpl->kfifo.out;
。
私は何を見逃していますか? Linuxはこのオーバーフローをどのように、どこで処理しますか?
以下のコードは私が言及した__kfifo_inで、Linux 5.4で見つかりました。
unsigned int __kfifo_in(struct __kfifo *fifo,
const void *buf, unsigned int len)
{
unsigned int l;
l = kfifo_unused(fifo);
if (len > l)
len = l;
kfifo_copy_in(fifo, buf, len, fifo->in);
fifo->in += len;
return len;
}
答え1
in
はfifoにプッシュされた合計バイト数、out
fifoからポップされた合計バイト数です。論理的にはin
常に> =out
ですが、すべての有限整数表現にはオーバーフローがあります。
unsigned intがシングルバイト(範囲0..255)で表されると仮定すると、256バイトをプッシュしますが、255バイトのみがポップされます。この場合はkfifo_unused
返されます。
(fifo->マスク + 1) - (fifo->in - fifo->out) = (full_queue_space) -(used_space) = (remaning_space) = (full_queue_space) -(0-255) = (full_queue_space) - (1 ) 。
実際、0x00 - 0xFF = 0x01を表すのに1バイトが使用されます。