mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-11 06:16:49 +00:00
Bind spin semantics to Guardian
This commit is contained in:
parent
208d5aa62d
commit
a77e653db6
@ -1,16 +1,18 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
task::{disable_preempt, DisabledPreemptGuard},
|
task::{atomic_mode::AsAtomicModeGuard, disable_preempt, DisabledPreemptGuard},
|
||||||
trap::{disable_local, DisabledLocalIrqGuard},
|
trap::{disable_local, DisabledLocalIrqGuard},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A guardian that denotes the guard behavior for holding a lock.
|
/// A guardian that denotes the guard behavior for holding a spin-based lock.
|
||||||
pub trait Guardian {
|
///
|
||||||
/// The guard type for holding a spin lock or a write lock.
|
/// It at least ensures that the atomic mode is maintained while the lock is held.
|
||||||
type Guard: GuardTransfer;
|
pub trait SpinGuardian {
|
||||||
/// The guard type for holding a read lock.
|
/// The guard type for holding a spin lock or a spin-based write lock.
|
||||||
type ReadGuard: GuardTransfer;
|
type Guard: AsAtomicModeGuard + GuardTransfer;
|
||||||
|
/// The guard type for holding a spin-based read lock.
|
||||||
|
type ReadGuard: AsAtomicModeGuard + GuardTransfer;
|
||||||
|
|
||||||
/// Creates a new guard.
|
/// Creates a new guard.
|
||||||
fn guard() -> Self::Guard;
|
fn guard() -> Self::Guard;
|
||||||
@ -32,7 +34,7 @@ pub trait GuardTransfer {
|
|||||||
/// A guardian that disables preemption while holding a lock.
|
/// A guardian that disables preemption while holding a lock.
|
||||||
pub struct PreemptDisabled;
|
pub struct PreemptDisabled;
|
||||||
|
|
||||||
impl Guardian for PreemptDisabled {
|
impl SpinGuardian for PreemptDisabled {
|
||||||
type Guard = DisabledPreemptGuard;
|
type Guard = DisabledPreemptGuard;
|
||||||
type ReadGuard = DisabledPreemptGuard;
|
type ReadGuard = DisabledPreemptGuard;
|
||||||
|
|
||||||
@ -53,7 +55,7 @@ impl Guardian for PreemptDisabled {
|
|||||||
/// context, then it is ok not to use this guardian in the process context.
|
/// context, then it is ok not to use this guardian in the process context.
|
||||||
pub struct LocalIrqDisabled;
|
pub struct LocalIrqDisabled;
|
||||||
|
|
||||||
impl Guardian for LocalIrqDisabled {
|
impl SpinGuardian for LocalIrqDisabled {
|
||||||
type Guard = DisabledLocalIrqGuard;
|
type Guard = DisabledLocalIrqGuard;
|
||||||
type ReadGuard = DisabledLocalIrqGuard;
|
type ReadGuard = DisabledLocalIrqGuard;
|
||||||
|
|
||||||
@ -79,7 +81,7 @@ impl Guardian for LocalIrqDisabled {
|
|||||||
/// [`SpinLock`]: super::SpinLock
|
/// [`SpinLock`]: super::SpinLock
|
||||||
pub struct WriteIrqDisabled;
|
pub struct WriteIrqDisabled;
|
||||||
|
|
||||||
impl Guardian for WriteIrqDisabled {
|
impl SpinGuardian for WriteIrqDisabled {
|
||||||
type Guard = DisabledLocalIrqGuard;
|
type Guard = DisabledLocalIrqGuard;
|
||||||
type ReadGuard = DisabledPreemptGuard;
|
type ReadGuard = DisabledPreemptGuard;
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ use crate::{
|
|||||||
cpu::{AtomicCpuSet, CpuId, CpuSet, PinCurrentCpu},
|
cpu::{AtomicCpuSet, CpuId, CpuSet, PinCurrentCpu},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
sync::SpinLock,
|
sync::SpinLock,
|
||||||
|
task::atomic_mode::AsAtomicModeGuard,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A RCU monitor ensures the completion of _grace periods_ by keeping track
|
/// A RCU monitor ensures the completion of _grace periods_ by keeping track
|
||||||
@ -42,7 +43,7 @@ impl RcuMonitor {
|
|||||||
// GP.
|
// GP.
|
||||||
let callbacks = {
|
let callbacks = {
|
||||||
let mut state = self.state.disable_irq().lock();
|
let mut state = self.state.disable_irq().lock();
|
||||||
let cpu = state.guard().current_cpu();
|
let cpu = state.as_atomic_mode_guard().current_cpu();
|
||||||
if state.current_gp.is_complete() {
|
if state.current_gp.is_complete() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
#![expect(dead_code)]
|
|
||||||
|
|
||||||
use alloc::sync::Arc;
|
use alloc::sync::Arc;
|
||||||
use core::{
|
use core::{
|
||||||
cell::UnsafeCell,
|
cell::UnsafeCell,
|
||||||
@ -15,9 +13,10 @@ use core::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
guard::{GuardTransfer, Guardian},
|
guard::{GuardTransfer, SpinGuardian},
|
||||||
PreemptDisabled,
|
PreemptDisabled,
|
||||||
};
|
};
|
||||||
|
use crate::task::atomic_mode::AsAtomicModeGuard;
|
||||||
|
|
||||||
/// Spin-based Read-write Lock
|
/// Spin-based Read-write Lock
|
||||||
///
|
///
|
||||||
@ -125,7 +124,7 @@ impl<T, G> RwLock<T, G> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized, G: Guardian> RwLock<T, G> {
|
impl<T: ?Sized, G: SpinGuardian> RwLock<T, G> {
|
||||||
/// Acquires a read lock and spin-wait until it can be acquired.
|
/// Acquires a read lock and spin-wait until it can be acquired.
|
||||||
///
|
///
|
||||||
/// The calling thread will spin-wait until there are no writers or
|
/// The calling thread will spin-wait until there are no writers or
|
||||||
@ -360,29 +359,29 @@ impl<T: ?Sized + fmt::Debug, G> fmt::Debug for RwLock<T, G> {
|
|||||||
unsafe impl<T: ?Sized + Send, G> Send for RwLock<T, G> {}
|
unsafe impl<T: ?Sized + Send, G> Send for RwLock<T, G> {}
|
||||||
unsafe impl<T: ?Sized + Send + Sync, G> Sync for RwLock<T, G> {}
|
unsafe impl<T: ?Sized + Send + Sync, G> Sync for RwLock<T, G> {}
|
||||||
|
|
||||||
impl<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: Guardian> !Send
|
impl<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: SpinGuardian> !Send
|
||||||
for RwLockWriteGuard_<T, R, G>
|
for RwLockWriteGuard_<T, R, G>
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
unsafe impl<T: ?Sized + Sync, R: Deref<Target = RwLock<T, G>> + Clone + Sync, G: Guardian> Sync
|
unsafe impl<T: ?Sized + Sync, R: Deref<Target = RwLock<T, G>> + Clone + Sync, G: SpinGuardian> Sync
|
||||||
for RwLockWriteGuard_<T, R, G>
|
for RwLockWriteGuard_<T, R, G>
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: Guardian> !Send
|
impl<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: SpinGuardian> !Send
|
||||||
for RwLockReadGuard_<T, R, G>
|
for RwLockReadGuard_<T, R, G>
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
unsafe impl<T: ?Sized + Sync, R: Deref<Target = RwLock<T, G>> + Clone + Sync, G: Guardian> Sync
|
unsafe impl<T: ?Sized + Sync, R: Deref<Target = RwLock<T, G>> + Clone + Sync, G: SpinGuardian> Sync
|
||||||
for RwLockReadGuard_<T, R, G>
|
for RwLockReadGuard_<T, R, G>
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: Guardian> !Send
|
impl<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: SpinGuardian> !Send
|
||||||
for RwLockUpgradeableGuard_<T, R, G>
|
for RwLockUpgradeableGuard_<T, R, G>
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
unsafe impl<T: ?Sized + Sync, R: Deref<Target = RwLock<T, G>> + Clone + Sync, G: Guardian> Sync
|
unsafe impl<T: ?Sized + Sync, R: Deref<Target = RwLock<T, G>> + Clone + Sync, G: SpinGuardian> Sync
|
||||||
for RwLockUpgradeableGuard_<T, R, G>
|
for RwLockUpgradeableGuard_<T, R, G>
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -390,18 +389,26 @@ unsafe impl<T: ?Sized + Sync, R: Deref<Target = RwLock<T, G>> + Clone + Sync, G:
|
|||||||
/// A guard that provides immutable data access.
|
/// A guard that provides immutable data access.
|
||||||
#[clippy::has_significant_drop]
|
#[clippy::has_significant_drop]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub struct RwLockReadGuard_<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: Guardian> {
|
pub struct RwLockReadGuard_<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: SpinGuardian> {
|
||||||
guard: G::ReadGuard,
|
guard: G::ReadGuard,
|
||||||
inner: R,
|
inner: R,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: SpinGuardian> AsAtomicModeGuard
|
||||||
|
for RwLockReadGuard_<T, R, G>
|
||||||
|
{
|
||||||
|
fn as_atomic_mode_guard(&self) -> &dyn crate::task::atomic_mode::InAtomicMode {
|
||||||
|
self.guard.as_atomic_mode_guard()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A guard that provides shared read access to the data protected by a [`RwLock`].
|
/// A guard that provides shared read access to the data protected by a [`RwLock`].
|
||||||
pub type RwLockReadGuard<'a, T, G> = RwLockReadGuard_<T, &'a RwLock<T, G>, G>;
|
pub type RwLockReadGuard<'a, T, G> = RwLockReadGuard_<T, &'a RwLock<T, G>, G>;
|
||||||
|
|
||||||
/// A guard that provides shared read access to the data protected by a `Arc<RwLock>`.
|
/// A guard that provides shared read access to the data protected by a `Arc<RwLock>`.
|
||||||
pub type ArcRwLockReadGuard<T, G> = RwLockReadGuard_<T, Arc<RwLock<T, G>>, G>;
|
pub type ArcRwLockReadGuard<T, G> = RwLockReadGuard_<T, Arc<RwLock<T, G>>, G>;
|
||||||
|
|
||||||
impl<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: Guardian> Deref
|
impl<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: SpinGuardian> Deref
|
||||||
for RwLockReadGuard_<T, R, G>
|
for RwLockReadGuard_<T, R, G>
|
||||||
{
|
{
|
||||||
type Target = T;
|
type Target = T;
|
||||||
@ -411,7 +418,7 @@ impl<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: Guardian> Deref
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: Guardian> Drop
|
impl<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: SpinGuardian> Drop
|
||||||
for RwLockReadGuard_<T, R, G>
|
for RwLockReadGuard_<T, R, G>
|
||||||
{
|
{
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
@ -419,7 +426,7 @@ impl<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: Guardian> Drop
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized + fmt::Debug, R: Deref<Target = RwLock<T, G>> + Clone, G: Guardian> fmt::Debug
|
impl<T: ?Sized + fmt::Debug, R: Deref<Target = RwLock<T, G>> + Clone, G: SpinGuardian> fmt::Debug
|
||||||
for RwLockReadGuard_<T, R, G>
|
for RwLockReadGuard_<T, R, G>
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
@ -428,17 +435,25 @@ impl<T: ?Sized + fmt::Debug, R: Deref<Target = RwLock<T, G>> + Clone, G: Guardia
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A guard that provides mutable data access.
|
/// A guard that provides mutable data access.
|
||||||
pub struct RwLockWriteGuard_<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: Guardian> {
|
pub struct RwLockWriteGuard_<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: SpinGuardian> {
|
||||||
guard: G::Guard,
|
guard: G::Guard,
|
||||||
inner: R,
|
inner: R,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: SpinGuardian> AsAtomicModeGuard
|
||||||
|
for RwLockWriteGuard_<T, R, G>
|
||||||
|
{
|
||||||
|
fn as_atomic_mode_guard(&self) -> &dyn crate::task::atomic_mode::InAtomicMode {
|
||||||
|
self.guard.as_atomic_mode_guard()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A guard that provides exclusive write access to the data protected by a [`RwLock`].
|
/// A guard that provides exclusive write access to the data protected by a [`RwLock`].
|
||||||
pub type RwLockWriteGuard<'a, T, G> = RwLockWriteGuard_<T, &'a RwLock<T, G>, G>;
|
pub type RwLockWriteGuard<'a, T, G> = RwLockWriteGuard_<T, &'a RwLock<T, G>, G>;
|
||||||
/// A guard that provides exclusive write access to the data protected by a `Arc<RwLock>`.
|
/// A guard that provides exclusive write access to the data protected by a `Arc<RwLock>`.
|
||||||
pub type ArcRwLockWriteGuard<T, G> = RwLockWriteGuard_<T, Arc<RwLock<T, G>>, G>;
|
pub type ArcRwLockWriteGuard<T, G> = RwLockWriteGuard_<T, Arc<RwLock<T, G>>, G>;
|
||||||
|
|
||||||
impl<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: Guardian> Deref
|
impl<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: SpinGuardian> Deref
|
||||||
for RwLockWriteGuard_<T, R, G>
|
for RwLockWriteGuard_<T, R, G>
|
||||||
{
|
{
|
||||||
type Target = T;
|
type Target = T;
|
||||||
@ -448,7 +463,9 @@ impl<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: Guardian> Deref
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: Guardian> RwLockWriteGuard_<T, R, G> {
|
impl<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: SpinGuardian>
|
||||||
|
RwLockWriteGuard_<T, R, G>
|
||||||
|
{
|
||||||
/// Atomically downgrades a write guard to an upgradeable reader guard.
|
/// Atomically downgrades a write guard to an upgradeable reader guard.
|
||||||
///
|
///
|
||||||
/// This method always succeeds because the lock is exclusively held by the writer.
|
/// This method always succeeds because the lock is exclusively held by the writer.
|
||||||
@ -479,7 +496,7 @@ impl<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: Guardian> RwLockWrit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: Guardian> DerefMut
|
impl<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: SpinGuardian> DerefMut
|
||||||
for RwLockWriteGuard_<T, R, G>
|
for RwLockWriteGuard_<T, R, G>
|
||||||
{
|
{
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
@ -487,7 +504,7 @@ impl<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: Guardian> DerefMut
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: Guardian> Drop
|
impl<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: SpinGuardian> Drop
|
||||||
for RwLockWriteGuard_<T, R, G>
|
for RwLockWriteGuard_<T, R, G>
|
||||||
{
|
{
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
@ -495,7 +512,7 @@ impl<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: Guardian> Drop
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized + fmt::Debug, R: Deref<Target = RwLock<T, G>> + Clone, G: Guardian> fmt::Debug
|
impl<T: ?Sized + fmt::Debug, R: Deref<Target = RwLock<T, G>> + Clone, G: SpinGuardian> fmt::Debug
|
||||||
for RwLockWriteGuard_<T, R, G>
|
for RwLockWriteGuard_<T, R, G>
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
@ -505,18 +522,29 @@ impl<T: ?Sized + fmt::Debug, R: Deref<Target = RwLock<T, G>> + Clone, G: Guardia
|
|||||||
|
|
||||||
/// A guard that provides immutable data access but can be atomically
|
/// A guard that provides immutable data access but can be atomically
|
||||||
/// upgraded to `RwLockWriteGuard`.
|
/// upgraded to `RwLockWriteGuard`.
|
||||||
pub struct RwLockUpgradeableGuard_<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: Guardian>
|
pub struct RwLockUpgradeableGuard_<
|
||||||
{
|
T: ?Sized,
|
||||||
|
R: Deref<Target = RwLock<T, G>> + Clone,
|
||||||
|
G: SpinGuardian,
|
||||||
|
> {
|
||||||
guard: G::Guard,
|
guard: G::Guard,
|
||||||
inner: R,
|
inner: R,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: SpinGuardian> AsAtomicModeGuard
|
||||||
|
for RwLockUpgradeableGuard_<T, R, G>
|
||||||
|
{
|
||||||
|
fn as_atomic_mode_guard(&self) -> &dyn crate::task::atomic_mode::InAtomicMode {
|
||||||
|
self.guard.as_atomic_mode_guard()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A upgradable guard that provides read access to the data protected by a [`RwLock`].
|
/// A upgradable guard that provides read access to the data protected by a [`RwLock`].
|
||||||
pub type RwLockUpgradeableGuard<'a, T, G> = RwLockUpgradeableGuard_<T, &'a RwLock<T, G>, G>;
|
pub type RwLockUpgradeableGuard<'a, T, G> = RwLockUpgradeableGuard_<T, &'a RwLock<T, G>, G>;
|
||||||
/// A upgradable guard that provides read access to the data protected by a `Arc<RwLock>`.
|
/// A upgradable guard that provides read access to the data protected by a `Arc<RwLock>`.
|
||||||
pub type ArcRwLockUpgradeableGuard<T, G> = RwLockUpgradeableGuard_<T, Arc<RwLock<T, G>>, G>;
|
pub type ArcRwLockUpgradeableGuard<T, G> = RwLockUpgradeableGuard_<T, Arc<RwLock<T, G>>, G>;
|
||||||
|
|
||||||
impl<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: Guardian>
|
impl<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: SpinGuardian>
|
||||||
RwLockUpgradeableGuard_<T, R, G>
|
RwLockUpgradeableGuard_<T, R, G>
|
||||||
{
|
{
|
||||||
/// Upgrades this upread guard to a write guard atomically.
|
/// Upgrades this upread guard to a write guard atomically.
|
||||||
@ -554,7 +582,7 @@ impl<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: Guardian>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: Guardian> Deref
|
impl<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: SpinGuardian> Deref
|
||||||
for RwLockUpgradeableGuard_<T, R, G>
|
for RwLockUpgradeableGuard_<T, R, G>
|
||||||
{
|
{
|
||||||
type Target = T;
|
type Target = T;
|
||||||
@ -564,7 +592,7 @@ impl<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: Guardian> Deref
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: Guardian> Drop
|
impl<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: SpinGuardian> Drop
|
||||||
for RwLockUpgradeableGuard_<T, R, G>
|
for RwLockUpgradeableGuard_<T, R, G>
|
||||||
{
|
{
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
@ -572,7 +600,7 @@ impl<T: ?Sized, R: Deref<Target = RwLock<T, G>> + Clone, G: Guardian> Drop
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized + fmt::Debug, R: Deref<Target = RwLock<T, G>> + Clone, G: Guardian> fmt::Debug
|
impl<T: ?Sized + fmt::Debug, R: Deref<Target = RwLock<T, G>> + Clone, G: SpinGuardian> fmt::Debug
|
||||||
for RwLockUpgradeableGuard_<T, R, G>
|
for RwLockUpgradeableGuard_<T, R, G>
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
@ -9,7 +9,8 @@ use core::{
|
|||||||
sync::atomic::{AtomicBool, Ordering},
|
sync::atomic::{AtomicBool, Ordering},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{guard::Guardian, LocalIrqDisabled, PreemptDisabled};
|
use super::{guard::SpinGuardian, LocalIrqDisabled, PreemptDisabled};
|
||||||
|
use crate::task::atomic_mode::AsAtomicModeGuard;
|
||||||
|
|
||||||
/// A spin lock.
|
/// A spin lock.
|
||||||
///
|
///
|
||||||
@ -67,7 +68,7 @@ impl<T: ?Sized> SpinLock<T, PreemptDisabled> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized, G: Guardian> SpinLock<T, G> {
|
impl<T: ?Sized, G: SpinGuardian> SpinLock<T, G> {
|
||||||
/// Acquires the spin lock.
|
/// Acquires the spin lock.
|
||||||
pub fn lock(&self) -> SpinLockGuard<T, G> {
|
pub fn lock(&self) -> SpinLockGuard<T, G> {
|
||||||
// Notice the guard must be created before acquiring the lock.
|
// Notice the guard must be created before acquiring the lock.
|
||||||
@ -152,19 +153,22 @@ pub type ArcSpinLockGuard<T, G> = SpinLockGuard_<T, Arc<SpinLock<T, G>>, G>;
|
|||||||
/// The guard of a spin lock.
|
/// The guard of a spin lock.
|
||||||
#[clippy::has_significant_drop]
|
#[clippy::has_significant_drop]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub struct SpinLockGuard_<T: ?Sized, R: Deref<Target = SpinLock<T, G>>, G: Guardian> {
|
pub struct SpinLockGuard_<T: ?Sized, R: Deref<Target = SpinLock<T, G>>, G: SpinGuardian> {
|
||||||
guard: G::Guard,
|
guard: G::Guard,
|
||||||
lock: R,
|
lock: R,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized, R: Deref<Target = SpinLock<T, G>>, G: Guardian> SpinLockGuard_<T, R, G> {
|
impl<T: ?Sized, R: Deref<Target = SpinLock<T, G>>, G: SpinGuardian> AsAtomicModeGuard
|
||||||
/// Returns a reference to the guard.
|
for SpinLockGuard_<T, R, G>
|
||||||
pub fn guard(&self) -> &G::Guard {
|
{
|
||||||
&self.guard
|
fn as_atomic_mode_guard(&self) -> &dyn crate::task::atomic_mode::InAtomicMode {
|
||||||
|
self.guard.as_atomic_mode_guard()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized, R: Deref<Target = SpinLock<T, G>>, G: Guardian> Deref for SpinLockGuard_<T, R, G> {
|
impl<T: ?Sized, R: Deref<Target = SpinLock<T, G>>, G: SpinGuardian> Deref
|
||||||
|
for SpinLockGuard_<T, R, G>
|
||||||
|
{
|
||||||
type Target = T;
|
type Target = T;
|
||||||
|
|
||||||
fn deref(&self) -> &T {
|
fn deref(&self) -> &T {
|
||||||
@ -172,7 +176,7 @@ impl<T: ?Sized, R: Deref<Target = SpinLock<T, G>>, G: Guardian> Deref for SpinLo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized, R: Deref<Target = SpinLock<T, G>>, G: Guardian> DerefMut
|
impl<T: ?Sized, R: Deref<Target = SpinLock<T, G>>, G: SpinGuardian> DerefMut
|
||||||
for SpinLockGuard_<T, R, G>
|
for SpinLockGuard_<T, R, G>
|
||||||
{
|
{
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
@ -180,13 +184,15 @@ impl<T: ?Sized, R: Deref<Target = SpinLock<T, G>>, G: Guardian> DerefMut
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized, R: Deref<Target = SpinLock<T, G>>, G: Guardian> Drop for SpinLockGuard_<T, R, G> {
|
impl<T: ?Sized, R: Deref<Target = SpinLock<T, G>>, G: SpinGuardian> Drop
|
||||||
|
for SpinLockGuard_<T, R, G>
|
||||||
|
{
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.lock.release_lock();
|
self.lock.release_lock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized + fmt::Debug, R: Deref<Target = SpinLock<T, G>>, G: Guardian> fmt::Debug
|
impl<T: ?Sized + fmt::Debug, R: Deref<Target = SpinLock<T, G>>, G: SpinGuardian> fmt::Debug
|
||||||
for SpinLockGuard_<T, R, G>
|
for SpinLockGuard_<T, R, G>
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
@ -194,11 +200,14 @@ impl<T: ?Sized + fmt::Debug, R: Deref<Target = SpinLock<T, G>>, G: Guardian> fmt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized, R: Deref<Target = SpinLock<T, G>>, G: Guardian> !Send for SpinLockGuard_<T, R, G> {}
|
impl<T: ?Sized, R: Deref<Target = SpinLock<T, G>>, G: SpinGuardian> !Send
|
||||||
|
for SpinLockGuard_<T, R, G>
|
||||||
// SAFETY: `SpinLockGuard_` can be shared between tasks/threads in same CPU.
|
{
|
||||||
// As `lock()` is only called when there are no race conditions caused by interrupts.
|
}
|
||||||
unsafe impl<T: ?Sized + Sync, R: Deref<Target = SpinLock<T, G>> + Sync, G: Guardian> Sync
|
|
||||||
|
// SAFETY: `SpinLockGuard_` can be shared between tasks/threads in same CPU.
|
||||||
|
// As `lock()` is only called when there are no race conditions caused by interrupts.
|
||||||
|
unsafe impl<T: ?Sized + Sync, R: Deref<Target = SpinLock<T, G>> + Sync, G: SpinGuardian> Sync
|
||||||
for SpinLockGuard_<T, R, G>
|
for SpinLockGuard_<T, R, G>
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user