audiocore: Fix small race window in get_fifo_read_value_blocking
In theory, the FIFO interrupt could occur after getting the fifo_read_value and reenabling interrupts, but before __wfi is called, causing a deadlock. Fix this by calling __wfi with interrupts still disabled. It will return immediately if an interrupt is pending. Add two __nop to ensure that the CPU has enough instructions between enabling interrupts and disabling them again at the top of the loop. Signed-off-by: Matthias Blankertz <matthias@blankertz.org>
This commit is contained in:
@@ -50,10 +50,14 @@ static uint32_t get_fifo_read_value_blocking(struct audiocore_obj *obj)
|
||||
const long flags = save_and_disable_interrupts();
|
||||
const uint32_t value = obj->fifo_read_value;
|
||||
obj->fifo_read_value = 0;
|
||||
restore_interrupts(flags);
|
||||
if (value & AUDIOCORE_FIFO_DATA_FLAG)
|
||||
if (value & AUDIOCORE_FIFO_DATA_FLAG) {
|
||||
restore_interrupts(flags);
|
||||
return value & ~AUDIOCORE_FIFO_DATA_FLAG;
|
||||
}
|
||||
__wfi();
|
||||
restore_interrupts(flags);
|
||||
__nop(); // Ensure at least two instructions between enable interrupts and subsequent disable
|
||||
__nop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user