diff --git a/os/src/batch.rs b/os/src/batch.rs index fbe94cd5..f2a0d649 100644 --- a/os/src/batch.rs +++ b/os/src/batch.rs @@ -105,16 +105,17 @@ pub fn init() { } pub fn print_app_info() { - APP_MANAGER.upsafe_access().print_app_info(); + APP_MANAGER.exclusive_access().print_app_info(); } pub fn run_next_app() -> ! { - let app_manager = APP_MANAGER.upsafe_access(); + let mut app_manager = APP_MANAGER.exclusive_access(); let current_app = app_manager.get_current_app(); unsafe { app_manager.load_app(current_app); } app_manager.move_to_next_app(); + drop(app_manager); extern "C" { fn __restore(cx_addr: usize); } unsafe { __restore(KERNEL_STACK.push_context( diff --git a/os/src/sync/up.rs b/os/src/sync/up.rs index 849ac4bc..642668c1 100644 --- a/os/src/sync/up.rs +++ b/os/src/sync/up.rs @@ -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 { /// inner data - data: T, + inner: RefCell, } unsafe impl Sync for UPSafeCell {} @@ -16,12 +18,10 @@ impl UPSafeCell { /// 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() } } \ No newline at end of file