diff options
| -rw-r--r-- | .gitignore | 3 | ||||
| -rw-r--r-- | Cargo.toml | 8 | ||||
| -rw-r--r-- | src/lib.rs | 2 | ||||
| -rw-r--r-- | src/sync.rs | 83 |
4 files changed, 96 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1a1e473 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/target +/Cargo.lock +*.swp diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..7d9f756 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "os_pic" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..1808de4 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,2 @@ +#![no_std] +pub mod sync; diff --git a/src/sync.rs b/src/sync.rs new file mode 100644 index 0000000..44c060e --- /dev/null +++ b/src/sync.rs @@ -0,0 +1,83 @@ +//! # Synchronization module +//! +//! Provides synchronization objects for thread-safe memory sharing. +use core::cell::UnsafeCell; +use core::marker::{Send, Sized, Sync}; +use core::ops::FnOnce; + +/// # Synchronization interfaces +/// +/// Provides Synchronization traits. +pub mod interface { + use core::ops::FnOnce; + /// # Mutex Trait + /// + /// Basic Locking primitive to allow single-process access to data + pub trait Mutex { + /// # The data + /// + /// Each mutex protects some internal data from modification across + /// processes when it is in use. This is important if the process + /// is preempted while the function is using it. + type Data; + /// # Locking mechanism + /// + /// Locks the mutex to access the data in a closure. + /// The data can be read and modified in this closure without worry + /// of poisoning the data across processes. + fn lock<'a, R>(&'a self, f: impl FnOnce(&'a mut Self::Data) -> R) -> R; + } + /// # Initializable + /// + /// Initializable type + pub trait Initializable { + fn init(&mut self); + } +} + +/// # Basic Lock Structure +pub struct NullLock<T> +where + T: ?Sized, +{ + /// The internal data to safely share + data: UnsafeCell<T>, +} + +/// # Allow thread sharing +unsafe impl<T> Send for NullLock<T> where T: ?Sized + Send {} +/// # Allow thread sharing +unsafe impl<T> Sync for NullLock<T> where T: ?Sized + Send {} + +impl<T> NullLock<T> { + /// # Create a new instance of the lock + pub const fn new(data: T) -> Self { + Self { + data: UnsafeCell::new(data), + } + } +} + +impl<T: interface::Initializable> NullLock<T> { + pub fn init(&self) { + use interface::Mutex; + self.lock(|initializable| { + initializable.init(); + }); + } +} + +impl<T> interface::Mutex for NullLock<T> { + /// # Underlying data of the lock + type Data = T; + + /// # Locking mechanism + /// + /// Locks the Mutex, and passes a mutable reference + /// to the encapsulated data to a closure. + fn lock<'a, R>(&'a self, f: impl FnOnce(&'a mut T) -> R) -> R { + let data = unsafe { &mut *self.data.get() }; + + f(data) + } +} |
