mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-08 21:06:48 +00:00
Move Guardian
to guard.rs
This commit is contained in:
parent
9e814251df
commit
29659dbc98
54
ostd/src/sync/guard.rs
Normal file
54
ostd/src/sync/guard.rs
Normal 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()
|
||||
}
|
||||
}
|
@ -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},
|
||||
};
|
||||
|
@ -14,7 +14,10 @@ use core::{
|
||||
},
|
||||
};
|
||||
|
||||
use super::{spin::Guardian, GuardTransfer, PreemptDisabled};
|
||||
use super::{
|
||||
guard::{GuardTransfer, Guardian},
|
||||
PreemptDisabled,
|
||||
};
|
||||
|
||||
/// Spin-based Read-write Lock
|
||||
///
|
||||
|
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user