Crate interrupt_mutex
source ·Expand description
A mutex for sharing data with interrupt handlers or signal handlers.
Using normal mutexes to share data with interrupt handlers may result in deadlocks. This is because interrupts may be raised while the mutex is being held on the same thread.
InterruptMutex
wraps another mutex and disables interrupts while the inner mutex is locked.
When the mutex is unlocked, the previous interrupt state is restored.
This makes InterruptMutex
suitable for sharing data with interrupts.
When used in bare-metal environments with spinlocks, locking the mutex corresponds to Linux’s spin_lock_irqsave
and unlocking corresponds to spin_unlock_irqrestore
.
See the Unreliable Guide To Locking — The Linux Kernel documentation.
While spin_lock_irqsave(lock, flags)
saves the interrupt flags in the explicit flags
argument, InterruptMutex
saves the interrupt flags internally.
Caveats
Holding an InterruptMutexGuard
does not guarantee that interrupts are disabled.
Dropping guards from different InterruptMutex
es in the wrong order might enable interrupts prematurely.
Similarly, you can just enable interrupts manually while holding a guard.
Examples
// Make a mutex of your choice into an `InterruptMutex`.
type InterruptMutex<T> = interrupt_mutex::InterruptMutex<parking_lot::RawMutex, T>;
static X: InterruptMutex<Vec<i32>> = InterruptMutex::new(Vec::new());
fn interrupt_handler() {
X.lock().push(1);
}
let v = X.lock();
// Raise an interrupt
raise_interrupt();
assert_eq!(*v, vec![]);
drop(v);
// The interrupt handler runs
let v = X.lock();
assert_eq!(*v, vec![1]);
drop(v);
Structs
- A mutex for sharing data with interrupt handlers or signal handlers.
Type Aliases
- A
lock_api::Mutex
based onRawInterruptMutex
. - A
lock_api::MutexGuard
based onRawInterruptMutex
.