Linuxキューは、入力/出力位置(__kfifo.in/__kfifo.out)のオーバーフローをどのように処理しますか?

Linuxキューは、入力/出力位置(__kfifo.in/__kfifo.out)のオーバーフローをどのように処理しますか?

私は現在、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にプッシュされた合計バイト数、outfifoからポップされた合計バイト数です。論理的には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バイトが使用されます。

関連情報