Files
k-os/crates/adapter-riscv/src/kernel_cell.rs

36 lines
1005 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>>,
}
// Single-core: no concurrent access. Initialized once before traps are enabled.
unsafe impl<T> Sync for KernelCell<T> {}
impl<T> KernelCell<T> {
pub const fn uninit() -> Self {
Self {
initialized: AtomicBool::new(false),
inner: UnsafeCell::new(MaybeUninit::uninit()),
}
}
pub fn init(&self, value: T) {
unsafe { (*self.inner.get()).write(value) };
self.initialized.store(true, Ordering::Release);
}
pub fn get(&self) -> &T {
debug_assert!(self.initialized.load(Ordering::Acquire));
unsafe { (*self.inner.get()).assume_init_ref() }
}
pub fn get_mut(&self) -> &mut T {
debug_assert!(self.initialized.load(Ordering::Acquire));
unsafe { (*self.inner.get()).assume_init_mut() }
}
}