diff --git a/ch2/os/src/sync/mod.rs b/ch2/os/src/sync/mod.rs new file mode 100644 index 0000000..1ccdd2e --- /dev/null +++ b/ch2/os/src/sync/mod.rs @@ -0,0 +1,4 @@ +//! Synchronization and interior mutability primitives + +mod up; +pub use up::UPSafeCell; diff --git a/ch2/os/src/sync/up.rs b/ch2/os/src/sync/up.rs new file mode 100644 index 0000000..e8ba20c --- /dev/null +++ b/ch2/os/src/sync/up.rs @@ -0,0 +1,31 @@ +//! Uniprocessor interior mutability primitives + +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 +/// `exclusive_access`. +pub struct UPSafeCell { + /// inner data + inner: RefCell, +} + +unsafe impl Sync for UPSafeCell {} + +impl UPSafeCell { + /// User is responsible to guarantee that inner struct is only used in + /// uniprocessor. + pub unsafe fn new(value: T) -> Self { + Self { + inner: RefCell::new(value), + } + } + /// Exclusive access inner data in UPSafeCell. Panic if the data has been borrowed. + pub fn exclusive_access(&self) -> RefMut<'_, T> { + self.inner.borrow_mut() + } +}