diff --git a/framework/aster-frame/src/sync/mod.rs b/framework/aster-frame/src/sync/mod.rs index 516d4c9a4..cdbb488d2 100644 --- a/framework/aster-frame/src/sync/mod.rs +++ b/framework/aster-frame/src/sync/mod.rs @@ -13,7 +13,7 @@ mod wait; // pub use self::rcu::{pass_quiescent_state, OwnerPtr, Rcu, RcuReadGuard, RcuReclaimer}; pub use self::{ atomic_bits::AtomicBits, - mutex::{Mutex, MutexGuard}, + mutex::{ArcMutexGuard, Mutex, MutexGuard}, rwlock::{ ArcRwLockReadGuard, ArcRwLockUpgradeableGuard, ArcRwLockWriteGuard, RwLock, RwLockReadGuard, RwLockUpgradeableGuard, RwLockWriteGuard, diff --git a/framework/aster-frame/src/sync/mutex.rs b/framework/aster-frame/src/sync/mutex.rs index d5925b113..8e1814aa1 100644 --- a/framework/aster-frame/src/sync/mutex.rs +++ b/framework/aster-frame/src/sync/mutex.rs @@ -1,5 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 +use alloc::sync::Arc; use core::{ cell::UnsafeCell, fmt, @@ -35,11 +36,29 @@ impl Mutex { self.queue.wait_until(|| self.try_lock()) } + /// Acquire the mutex through an [`Arc`]. + /// + /// The method is similar to [`Self::lock`], but it doesn't have the requirement + /// for compile-time checked lifetimes of the mutex guard. + pub fn lock_arc(self: &Arc) -> ArcMutexGuard { + self.queue.wait_until(|| self.try_lock_arc()) + } + /// Try Acquire the mutex immedidately. pub fn try_lock(&self) -> Option> { // Cannot be reduced to `then_some`, or the possible dropping of the temporary // guard will cause an unexpected unlock. - self.acquire_lock().then(|| MutexGuard::new(self)) + self.acquire_lock().then_some(MutexGuard { mutex: self }) + } + + /// Try acquire the mutex through an [`Arc`]. + /// + /// The method is similar to [`Self::try_lock`], but it doesn't have the requirement + /// for compile-time checked lifetimes of the mutex guard. + pub fn try_lock_arc(self: &Arc) -> Option> { + self.acquire_lock().then(|| ArcMutexGuard { + mutex: self.clone(), + }) } /// Release the mutex and wake up one thread which is blocked on this mutex. @@ -69,17 +88,14 @@ unsafe impl Send for Mutex {} unsafe impl Sync for Mutex {} #[clippy::has_significant_drop] -pub struct MutexGuard<'a, T: ?Sized> { - mutex: &'a Mutex, +pub struct MutexGuard_>> { + mutex: R, } -impl<'a, T: ?Sized> MutexGuard<'a, T> { - fn new(mutex: &'a Mutex) -> MutexGuard<'a, T> { - MutexGuard { mutex } - } -} +pub type MutexGuard<'a, T> = MutexGuard_>; +pub type ArcMutexGuard = MutexGuard_>>; -impl<'a, T: ?Sized> Deref for MutexGuard<'a, T> { +impl>> Deref for MutexGuard_ { type Target = T; fn deref(&self) -> &Self::Target { @@ -87,24 +103,24 @@ impl<'a, T: ?Sized> Deref for MutexGuard<'a, T> { } } -impl<'a, T: ?Sized> DerefMut for MutexGuard<'a, T> { +impl>> DerefMut for MutexGuard_ { fn deref_mut(&mut self) -> &mut Self::Target { unsafe { &mut *self.mutex.val.get() } } } -impl<'a, T: ?Sized> Drop for MutexGuard<'a, T> { +impl>> Drop for MutexGuard_ { fn drop(&mut self) { self.mutex.unlock(); } } -impl<'a, T: ?Sized + fmt::Debug> fmt::Debug for MutexGuard<'a, T> { +impl>> fmt::Debug for MutexGuard_ { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Debug::fmt(&**self, f) } } -impl<'a, T: ?Sized> !Send for MutexGuard<'a, T> {} +impl>> !Send for MutexGuard_ {} -unsafe impl Sync for MutexGuard<'_, T> {} +unsafe impl> + Sync> Sync for MutexGuard_ {} diff --git a/kernel/aster-nix/src/fs/exfat/fat.rs b/kernel/aster-nix/src/fs/exfat/fat.rs index 3e8cb7a70..5000253f8 100644 --- a/kernel/aster-nix/src/fs/exfat/fat.rs +++ b/kernel/aster-nix/src/fs/exfat/fat.rs @@ -202,7 +202,7 @@ impl ExfatChain { fn alloc_cluster_from_empty( &mut self, num_to_be_allocated: u32, - bitmap: &mut MutexGuard<'_, ExfatBitmap>, + bitmap: &mut MutexGuard, sync_bitmap: bool, ) -> Result { // Search for a continuous chunk big enough @@ -228,7 +228,7 @@ impl ExfatChain { &mut self, num_to_be_allocated: u32, sync: bool, - bitmap: &mut MutexGuard<'_, ExfatBitmap>, + bitmap: &mut MutexGuard, ) -> Result { let fs = self.fs(); let mut alloc_start_cluster = 0; @@ -255,7 +255,7 @@ impl ExfatChain { start_physical_cluster: ClusterID, drop_num: u32, sync_bitmap: bool, - bitmap: &mut MutexGuard<'_, ExfatBitmap>, + bitmap: &mut MutexGuard, ) -> Result<()> { let fs = self.fs(); diff --git a/kernel/aster-nix/src/fs/exfat/fs.rs b/kernel/aster-nix/src/fs/exfat/fs.rs index 6cc38638e..d38ca7b1a 100644 --- a/kernel/aster-nix/src/fs/exfat/fs.rs +++ b/kernel/aster-nix/src/fs/exfat/fs.rs @@ -325,7 +325,7 @@ impl ExfatFS { self.super_block.cluster_size as usize * self.super_block.num_clusters as usize } - pub(super) fn lock(&self) -> MutexGuard<'_, ()> { + pub(super) fn lock(&self) -> MutexGuard<()> { self.mutex.lock() }