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

Interrupts are disabled on a best-effort basis.

Holding an InterruptMutexGuard does not guarantee that interrupts are disabled. Dropping guards from different InterruptMutexes 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