From af9a7aa7124300882f023c33d1b9e01f5a78c22c Mon Sep 17 00:00:00 2001 From: Julien CLEMENT Date: Tue, 20 Dec 2022 20:38:18 +0100 Subject: [PATCH] Add async mutex first version Signed-off-by: Julien CLEMENT --- src/lib.rs | 2 - src/utils/mod.rs | 4 +- src/utils/mutex.rs | 111 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 114 insertions(+), 3 deletions(-) create mode 100644 src/utils/mutex.rs diff --git a/src/lib.rs b/src/lib.rs index 58db943..0c74136 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,8 +19,6 @@ use drivers::vga::{self, Color, ColorCode}; use multiboot2::BootInformation; use task::{executor::Executor, keyboard, Task}; -use fs::iso::iso9660::{IsoDir, IsoPrimVolDesc, MultiEndian32}; - #[alloc_error_handler] fn alloc_error_handler(layout: alloc::alloc::Layout) -> ! { panic!("Allocation error: {:?}", layout) diff --git a/src/utils/mod.rs b/src/utils/mod.rs index c2664f7..bfc745d 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1,3 +1,5 @@ pub mod serialize; +pub mod mutex; -pub use serialize::unserialize; \ No newline at end of file +pub use serialize::unserialize; +pub use mutex::AsyncMutex; \ No newline at end of file diff --git a/src/utils/mutex.rs b/src/utils/mutex.rs new file mode 100644 index 0000000..6250f71 --- /dev/null +++ b/src/utils/mutex.rs @@ -0,0 +1,111 @@ +use core::future::Future; +use core::pin::Pin; +use core::cell::UnsafeCell; +use core::ops::{Deref, DerefMut, Drop}; +use core::sync::atomic::{AtomicBool, Ordering}; +use core::task::{Context, Poll}; +use alloc::rc::Rc; + +use futures_util::task::AtomicWaker; + +#[derive(Clone)] +struct Lock { + lock: Rc, + waker: Rc, +} + +pub struct AsyncMutex { + lock: Lock, + inner: UnsafeCell, +} + +pub struct AsyncMutexGuard<'a, T> +where + T: 'a, +{ + mutex: &'a AsyncMutex +} + +impl Lock { + fn new() -> Self { + Lock { + lock: Rc::new(AtomicBool::new(false)), + waker: Rc::new(AtomicWaker::new()), + } + } + + fn try_lock(&self) -> bool { + self.lock.swap(true, Ordering::Acquire) + } + + fn drop(&self) { + self.lock.swap(false, Ordering::Release); + self.waker.wake(); + } +} + +impl Future for Lock { + type Output = (); + + fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll { + if self.try_lock() { + return Poll::Ready(()); + } + + self.waker.register(&cx.waker()); + + match self.try_lock() { + true => { + self.waker.take(); + Poll::Ready(()) + }, + false => Poll::Pending, + } + } +} + +impl AsyncMutex { + pub fn new(val: T) -> Self { + AsyncMutex { + lock: Lock::new(), + inner: UnsafeCell::new(val), + } + } + + pub fn try_lock(&self) -> Option> { + if self.lock.try_lock() { + Some(AsyncMutexGuard { mutex: self }) + } else { + None + } + } + + pub async fn lock(&self) -> AsyncMutexGuard<'_, T> { + self.lock.clone().await; + AsyncMutexGuard { mutex: self } + } +} + + +impl Drop for AsyncMutexGuard<'_, T> { + fn drop(&mut self) { + self.mutex.lock.drop(); + } +} + +impl Deref for AsyncMutexGuard<'_, T> { + type Target = T; + fn deref(&self) -> &Self::Target { + unsafe { + &*self.mutex.inner.get() + } + } +} + +impl DerefMut for AsyncMutexGuard<'_, T> { + fn deref_mut(&mut self) -> &mut Self::Target { + unsafe { + &mut *self.mutex.inner.get() + } + } +} \ No newline at end of file