rust-embedded / rust-embedded/heapless
Queue not thread/interrupt safe?
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 2k
- Forks
- 253
- Avg merge
- 1d 2h
- Merged PRs (30d)
- 1
Description
I am developing in RISC-V and in my understanding the Queue is not thread or interrupt safe. Imagine the following scenario where an item is dequeued:
unsafe fn inner_dequeue(&self) -> Option<T> {
let current_head = self.head.load(Ordering::Relaxed); // holds head before second dequeue
// (1) interrupt or thread switch happens here, inner_dequeue is executed in second context
// -> head is incremented by second context
// current head is no longer up to date and still holds the not yet incremented value
if current_head == self.tail.load(Ordering::Acquire) {
None
} else {
// the same elemet is returned twice
// once here and once in the second context
let v = (self.buffer.get_unchecked(current_head).get() as *const T).read();
self.head
.store(Self::increment(current_head), Ordering::Release);
Some(v)
}
}
Imagine if the inner_dequeue function is interrupted at position (1), right between the load of the head and the tail and in the other context (either interrupt or different thread) inner_dequeue is executed. Now the head still is already incremented by the second context, but the original context still uses the old value. Like this, one value is returned/dequeued twice.
As far as I understand, the atomics do not prevent this behavior. Or at least not for the single core risv32imc target. Here, interrupts get disabled and re-enabled just for the two load instructions. But they are enabled in between the two loads:
// disable interrupts
let current_head = self.head.load(Ordering::Relaxed);
// enable interrupts
// disable interrupts
if current_head == self.tail.load(Ordering::Acquire) {
// disable interrupts
...
}
So I am not sure if thread/interrupt safety is guaranteed, but if it is, I would suggest using a critical section around the whole dequeue process.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing the Queue implementation around inner_dequeue and its atomic ordering. Reproduce the reported interleaving on the single-core RISC-V target with interrupts or concurrent execution, then inspect existing queue tests for coverage. Done means the thread and interrupt-safety guarantee is established or the issue is reduced to a documented, test-backed fix.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- embedded-iot
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100