Expand description
Safe per-CPU core mutable state on no_std platforms through exception masking.
This crate provides two main wrapper types: PerCore
to provide an instance of a value per
CPU core, where each core can access only its instance, and ExceptionLock
to guard a value
so that it can only be accessed while exceptions are masked. These may be combined with
RefCell
to provide safe per-core mutable state.
ExceptionLock
may also be combined with a spinlock-based mutex (such as one provided by the
spin
crate) to avoid deadlocks when accessing global mutable
state from exception handlers.
§Example
use core::cell::RefCell;
use percore::{exception_free, Cores, ExceptionLock, PerCore};
/// The total number of CPU cores in the target system.
const CORE_COUNT: usize = 2;
struct CoresImpl;
unsafe impl Cores for CoresImpl {
fn core_index() -> usize {
todo!("Return the index of the current CPU core, 0 or 1")
}
}
struct CoreState {
// Your per-core mutable state goes here...
foo: u32,
}
const EMPTY_CORE_STATE: ExceptionLock<RefCell<CoreState>> =
ExceptionLock::new(RefCell::new(CoreState { foo: 0 }));
static CORE_STATE: PerCore<ExceptionLock<RefCell<CoreState>>, CoresImpl, CORE_COUNT> =
PerCore::new([EMPTY_CORE_STATE; CORE_COUNT]);
fn main() {
// Mask exceptions while accessing mutable state.
exception_free(|token| {
// `token` proves that interrupts are masked, so we can safely access per-core mutable
// state.
CORE_STATE.get().borrow_mut(token).foo = 42;
});
}
Structs§
- Exception
Free - A token proving that exceptions are currently masked.
- Exception
Lock - Allows access to the given value only while exceptions are masked, allowing it to be shared between exception contexts on a given core.
- PerCore
- A type which allows values to be stored per CPU core. Only the value associated with the current CPU core can be accessed.
Traits§
- Cores
- Trait abstracting how to get the index of the current CPU core.
Functions§
- exception_
free - Runs the given function with exceptions masked.