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 long flags = save_and_disable_interrupts();
|
||||||
const uint32_t value = obj->fifo_read_value;
|
const uint32_t value = obj->fifo_read_value;
|
||||||
obj->fifo_read_value = 0;
|
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;
|
return value & ~AUDIOCORE_FIFO_DATA_FLAG;
|
||||||
|
}
|
||||||
__wfi();
|
__wfi();
|
||||||
|
restore_interrupts(flags);
|
||||||
|
__nop(); // Ensure at least two instructions between enable interrupts and subsequent disable
|
||||||
|
__nop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user