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

View File

@ -11,10 +11,7 @@ use core::{
sync::atomic::{AtomicBool, Ordering},
};
use crate::{
task::{disable_preempt, DisabledPreemptGuard},
trap::{disable_local, DisabledLocalIrqGuard},
};
use super::{guard::Guardian, LocalIrqDisabled, PreemptDisabled};
/// A spin lock.
///
@ -44,54 +41,6 @@ struct SpinLockInner<T: ?Sized> {
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> {
/// Creates a new spin lock.
pub const fn new(val: T) -> Self {