29 lines
838 B
Rust
29 lines
838 B
Rust
use core::cell::UnsafeCell;
|
|
use core::mem::MaybeUninit;
|
|
use core::sync::atomic::{AtomicBool, Ordering};
|
|
|
|
pub struct KernelCell<T> {
|
|
initialized: AtomicBool,
|
|
inner: UnsafeCell<MaybeUninit<T>>,
|
|
}
|
|
|
|
// Access is serialized by the kernel lock.
|
|
unsafe impl<T> Sync for KernelCell<T> {}
|
|
|
|
impl<T> KernelCell<T> {
|
|
/// Holds `value` from the start: built at compile time, so a large `T`
|
|
/// never lives on the stack.
|
|
pub const fn new(value: T) -> Self {
|
|
Self {
|
|
initialized: AtomicBool::new(true),
|
|
inner: UnsafeCell::new(MaybeUninit::new(value)),
|
|
}
|
|
}
|
|
|
|
/// Raw pointer to the kernel; callers must avoid aliasing `&mut`.
|
|
pub fn as_ptr(&self) -> *mut T {
|
|
debug_assert!(self.initialized.load(Ordering::Acquire));
|
|
unsafe { (*self.inner.get()).as_mut_ptr() }
|
|
}
|
|
}
|