From 25ac075ef13587125571c539faa72366d189f7df Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Tue, 22 Mar 2022 09:54:44 +0100 Subject: [PATCH] mutex --- src/lib.rs | 3 ++- src/linked_list.rs | 18 +++++++++++++++ src/mutex.rs | 55 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 src/linked_list.rs create mode 100644 src/mutex.rs diff --git a/src/lib.rs b/src/lib.rs index 64a29b3..68873ae 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1 +1,2 @@ -compile_error!("lol"); +mod linked_list; +mod mutex; diff --git a/src/linked_list.rs b/src/linked_list.rs new file mode 100644 index 0000000..ad10414 --- /dev/null +++ b/src/linked_list.rs @@ -0,0 +1,18 @@ +use std::ptr; +use std::sync::atomic::AtomicPtr; + +pub struct LinkedList { + head: AtomicPtr>, +} + +struct Node { + next: AtomicPtr>, +} + +impl LinkedList { + pub fn new() -> Self { + Self { + head: AtomicPtr::new(ptr::null_mut()), + } + } +} diff --git a/src/mutex.rs b/src/mutex.rs new file mode 100644 index 0000000..f52701b --- /dev/null +++ b/src/mutex.rs @@ -0,0 +1,55 @@ +use std::cell::UnsafeCell; +use std::ops::{Deref, DerefMut}; +use std::sync::atomic::{AtomicU8, Ordering}; + +const INIT: u8 = 0; +const ACQUIRED: u8 = 1; + +struct Mutex { + value: UnsafeCell, + status: AtomicU8, +} + +impl Mutex { + pub fn new(value: T) -> Self { + Self { + value, + status: AtomicU8::new(INIT), + } + } + + pub fn try_lock(&self) -> Option> { + if self + .status + .compare_exchange(INIT, ACQUIRED, Ordering::Acquire, Ordering::Relaxed) + { + Some(MutexGuard { mutex: self }) + } else { + None + } + } +} + +pub struct MutexGuard<'a, T> { + mutex: &'a Mutex, +} + +impl<'a, T> Deref for MutexGuard<'a, T> { + type Target = T; + + fn deref(&self) -> &Self::Target { + unsafe { &*self.mutex.value.get() } + } +} + +impl<'a, T> DerefMut for MutexGuard<'a, T> { + fn deref_mut(&mut self) -> &mut Self::Target { + unsafe { &mut *self.mutex.value.get() } + } +} + +impl<'a, T> Drop for MutexGuard<'a, T> { + fn drop(&mut self) { + self.mutex.status.store(INIT, Ordering::Release); + } +}