Move Guardian to guard.rs

This commit is contained in:
Ruihan Li 2024-12-03 10:35:27 +08:00 committed by Tate, Hongliang Tian
parent 9e814251df
commit 29659dbc98
4 changed files with 63 additions and 56 deletions

54
ostd/src/sync/guard.rs Normal file
View File

@ -0,0 +1,54 @@
// SPDX-License-Identifier: MPL-2.0
use crate::{
task::{disable_preempt, DisabledPreemptGuard},
trap::{disable_local, DisabledLocalIrqGuard},
};
/// A guardian that denotes the guard behavior for holding the spin lock.
pub trait Guardian {
/// The guard type.
type Guard: GuardTransfer;
/// Creates a new guard.
fn guard() -> Self::Guard;
}
/// The Guard can be transferred atomically.
pub trait GuardTransfer {
/// Atomically transfers the current guard to a new instance.
///
/// This function ensures that there are no 'gaps' between the destruction of the old guard and
/// the creation of the new guard, thereby maintaining the atomicity of guard transitions.
///
/// The original guard must be dropped immediately after calling this method.
fn transfer_to(&mut self) -> Self;
}
/// A guardian that disables preemption while holding the spin lock.
pub struct PreemptDisabled;
impl Guardian for PreemptDisabled {
type Guard = DisabledPreemptGuard;
fn guard() -> Self::Guard {
disable_preempt()
}
}
/// A guardian that disables IRQs while holding the spin lock.
///
/// This guardian would incur a certain time overhead over
/// [`PreemptDisabled']. So prefer avoiding using this guardian when
/// IRQ handlers are allowed to get executed while holding the
/// lock. For example, if a lock is never used in the interrupt
/// context, then it is ok not to use this guardian in the process context.
pub struct LocalIrqDisabled;
impl Guardian for LocalIrqDisabled {
type Guard = DisabledLocalIrqGuard;
fn guard() -> Self::Guard {
disable_local()
}
}

View File

@ -2,6 +2,7 @@
//! Useful synchronization primitives. //! Useful synchronization primitives.
mod guard;
mod mutex; mod mutex;
// TODO: refactor this rcu implementation // TODO: refactor this rcu implementation
// Comment out this module since it raises lint error // Comment out this module since it raises lint error
@ -12,7 +13,9 @@ mod spin;
mod wait; mod wait;
// pub use self::rcu::{pass_quiescent_state, OwnerPtr, Rcu, RcuReadGuard, RcuReclaimer}; // pub use self::rcu::{pass_quiescent_state, OwnerPtr, Rcu, RcuReadGuard, RcuReclaimer};
pub(crate) use self::guard::GuardTransfer;
pub use self::{ pub use self::{
guard::{LocalIrqDisabled, PreemptDisabled},
mutex::{ArcMutexGuard, Mutex, MutexGuard}, mutex::{ArcMutexGuard, Mutex, MutexGuard},
rwlock::{ rwlock::{
ArcRwLockReadGuard, ArcRwLockUpgradeableGuard, ArcRwLockWriteGuard, RwLock, ArcRwLockReadGuard, ArcRwLockUpgradeableGuard, ArcRwLockWriteGuard, RwLock,
@ -22,8 +25,6 @@ pub use self::{
ArcRwMutexReadGuard, ArcRwMutexUpgradeableGuard, ArcRwMutexWriteGuard, RwMutex, ArcRwMutexReadGuard, ArcRwMutexUpgradeableGuard, ArcRwMutexWriteGuard, RwMutex,
RwMutexReadGuard, RwMutexUpgradeableGuard, RwMutexWriteGuard, RwMutexReadGuard, RwMutexUpgradeableGuard, RwMutexWriteGuard,
}, },
spin::{ spin::{ArcSpinLockGuard, SpinLock, SpinLockGuard},
ArcSpinLockGuard, GuardTransfer, LocalIrqDisabled, PreemptDisabled, SpinLock, SpinLockGuard,
},
wait::{WaitQueue, Waiter, Waker}, wait::{WaitQueue, Waiter, Waker},
}; };

View File

@ -14,7 +14,10 @@ use core::{
}, },
}; };
use super::{spin::Guardian, GuardTransfer, PreemptDisabled}; use super::{
guard::{GuardTransfer, Guardian},
PreemptDisabled,
};
/// Spin-based Read-write Lock /// Spin-based Read-write Lock
/// ///

View File

@ -11,10 +11,7 @@ use core::{
sync::atomic::{AtomicBool, Ordering}, sync::atomic::{AtomicBool, Ordering},
}; };
use crate::{ use super::{guard::Guardian, LocalIrqDisabled, PreemptDisabled};
task::{disable_preempt, DisabledPreemptGuard},
trap::{disable_local, DisabledLocalIrqGuard},
};
/// A spin lock. /// A spin lock.
/// ///
@ -44,54 +41,6 @@ struct SpinLockInner<T: ?Sized> {
val: UnsafeCell<T>, val: UnsafeCell<T>,
} }
/// A guardian that denotes the guard behavior for holding the spin lock.
pub trait Guardian {
/// The guard type.
type Guard: GuardTransfer;
/// Creates a new guard.
fn guard() -> Self::Guard;
}
/// The Guard can be transferred atomically.
pub trait GuardTransfer {
/// Atomically transfers the current guard to a new instance.
///
/// This function ensures that there are no 'gaps' between the destruction of the old guard and
/// the creation of the new guard, thereby maintaining the atomicity of guard transitions.
///
/// The original guard must be dropped immediately after calling this method.
fn transfer_to(&mut self) -> Self;
}
/// A guardian that disables preemption while holding the spin lock.
pub struct PreemptDisabled;
impl Guardian for PreemptDisabled {
type Guard = DisabledPreemptGuard;
fn guard() -> Self::Guard {
disable_preempt()
}
}
/// A guardian that disables IRQs while holding the spin lock.
///
/// This guardian would incur a certain time overhead over
/// [`PreemptDisabled']. So prefer avoiding using this guardian when
/// IRQ handlers are allowed to get executed while holding the
/// lock. For example, if a lock is never used in the interrupt
/// context, then it is ok not to use this guardian in the process context.
pub struct LocalIrqDisabled;
impl Guardian for LocalIrqDisabled {
type Guard = DisabledLocalIrqGuard;
fn guard() -> Self::Guard {
disable_local()
}
}
impl<T, G> SpinLock<T, G> { impl<T, G> SpinLock<T, G> {
/// Creates a new spin lock. /// Creates a new spin lock.
pub const fn new(val: T) -> Self { pub const fn new(val: T) -> Self {