summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Cunningham <c@localhost>2022-08-23 20:53:30 -0700
committerChristian Cunningham <c@localhost>2022-08-23 20:53:30 -0700
commitac1679aa07db7cb78dbb1743f1c27bac449bc68e (patch)
tree8e2e35202b164c5f03dd5b91f91b52c39449a764
Initial commit
-rw-r--r--.gitignore3
-rw-r--r--Cargo.toml8
-rw-r--r--src/lib.rs2
-rw-r--r--src/sync.rs83
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)
+ }
+}