mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-15 16:26: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.
|
//! 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},
|
||||||
};
|
};
|
||||||
|
@ -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
|
||||||
///
|
///
|
||||||
|
@ -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 {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user