heapless icon indicating copy to clipboard operation
heapless copied to clipboard

MpMcQueue: enqueue enters infinite loop if queue is full (N >= 256)

Open sjorsdewit opened this issue 1 year ago • 1 comments

I'm using heapless-0.8.0 with the feature mpmc_large. Instances of MpMcQueue with N >= 256 can be constructed and appear to work correctly, but I think I found an edge case:

If the queue is already full and another enqueue is attempted, the function blocks in an inner busy loop. I suspect it has to do with the i8 it uses internally but replacing it with isize did not appear to fix this.

The issue can be reproduced by this test program:

#[test]
fn enqueue_full_256() {
    const CAPACITY: usize = 256;
    let q: MpMcQueue<u8, CAPACITY> = MpMcQueue::new();
    for n in 0..CAPACITY {
        // First CAPACITY enqueues are succesfull
        q.enqueue(0xAA).unwrap();
    }
    // Queue is full. This should fail, but instead triggers a busy loop for CAPACITY > 128
    q.enqueue(0x55).unwrap_err();
}

sjorsdewit avatar Feb 28 '24 12:02 sjorsdewit

I haven't looked at the implementation in detail, but

https://github.com/rust-embedded/heapless/blob/7bb2f71b5510494ba061f1bd6805a425769522fd/src/mpmc.rs#L219

and

https://github.com/rust-embedded/heapless/blob/7bb2f71b5510494ba061f1bd6805a425769522fd/src/mpmc.rs#L263

look suspicious.

reitermarkus avatar Feb 29 '24 21:02 reitermarkus