|
|
|
@ -1,13 +1,15 @@
|
|
|
|
|
/// Wrap a static data structure inside it so that we are
|
|
|
|
|
use core::cell::{RefCell, RefMut};
|
|
|
|
|
|
|
|
|
|
/// Wrap a static data structure inside it so that we are
|
|
|
|
|
/// able to access it without any `unsafe`.
|
|
|
|
|
///
|
|
|
|
|
/// We should only use it in uniprocessor.
|
|
|
|
|
///
|
|
|
|
|
/// In order to get mutable reference of inner data, call
|
|
|
|
|
/// `upsafe_access`.
|
|
|
|
|
/// In order to get mutable reference of inner data, call
|
|
|
|
|
/// `exclusive_access`.
|
|
|
|
|
pub struct UPSafeCell<T> {
|
|
|
|
|
/// inner data
|
|
|
|
|
data: T,
|
|
|
|
|
inner: RefCell<T>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsafe impl<T> Sync for UPSafeCell<T> {}
|
|
|
|
@ -16,12 +18,10 @@ impl<T> UPSafeCell<T> {
|
|
|
|
|
/// User is responsible to guarantee that inner struct is only used in
|
|
|
|
|
/// uniprocessor.
|
|
|
|
|
pub unsafe fn new(value: T) -> Self {
|
|
|
|
|
Self { data: value, }
|
|
|
|
|
Self { inner: RefCell::new(value) }
|
|
|
|
|
}
|
|
|
|
|
/// Mention that user should hold exactly one &mut T at a time.
|
|
|
|
|
pub fn upsafe_access(&self) -> &mut T {
|
|
|
|
|
unsafe {
|
|
|
|
|
&mut *(&self.data as *const _ as usize as *mut T)
|
|
|
|
|
}
|
|
|
|
|
/// Panic if the data has been borrowed.
|
|
|
|
|
pub fn exclusive_access(&self) -> RefMut<'_, T> {
|
|
|
|
|
self.inner.borrow_mut()
|
|
|
|
|
}
|
|
|
|
|
}
|