mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-08 12:56:48 +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
|
||||
|
||||
use crate::{
|
||||
task::{disable_preempt, DisabledPreemptGuard},
|
||||
task::{atomic_mode::AsAtomicModeGuard, disable_preempt, DisabledPreemptGuard},
|
||||
trap::{disable_local, DisabledLocalIrqGuard},
|
||||
};
|
||||
|
||||
/// A guardian that denotes the guard behavior for holding a lock.
|
||||
pub trait Guardian {
|
||||
/// The guard type for holding a spin lock or a write lock.
|
||||
type Guard: GuardTransfer;
|
||||
/// The guard type for holding a read lock.
|
||||
type ReadGuard: GuardTransfer;
|
||||
/// A guardian that denotes the guard behavior for holding a spin-based lock.
|
||||
///
|
||||
/// It at least ensures that the atomic mode is maintained while the lock is held.
|
||||
pub trait SpinGuardian {
|
||||
/// The guard type for holding a spin lock or a spin-based write lock.
|
||||
type Guard: AsAtomicModeGuard + GuardTransfer;
|
||||
/// The guard type for holding a spin-based read lock.
|
||||
type ReadGuard: AsAtomicModeGuard + GuardTransfer;
|
||||
|
||||
/// Creates a new guard.
|
||||
fn guard() -> Self::Guard;
|
||||
@ -32,7 +34,7 @@ pub trait GuardTransfer {
|
||||
/// A guardian that disables preemption while holding a lock.
|
||||
pub struct PreemptDisabled;
|
||||
|
||||
impl Guardian for PreemptDisabled {
|
||||
impl SpinGuardian for PreemptDisabled {
|
||||
type Guard = 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.
|
||||
pub struct LocalIrqDisabled;
|
||||
|
||||
impl Guardian for LocalIrqDisabled {
|
||||
impl SpinGuardian for LocalIrqDisabled {
|
||||
type Guard = DisabledLocalIrqGuard;
|
||||
type ReadGuard = DisabledLocalIrqGuard;
|
||||
|
||||
@ -79,7 +81,7 @@ impl Guardian for LocalIrqDisabled {
|
||||
/// [`SpinLock`]: super::SpinLock
|
||||
pub struct WriteIrqDisabled;
|
||||
|
||||
impl Guardian for WriteIrqDisabled {
|
||||
impl SpinGuardian for WriteIrqDisabled {
|
||||
type Guard = DisabledLocalIrqGuard;
|
||||
type ReadGuard = DisabledPreemptGuard;
|
||||
|
||||
|
@ -10,6 +10,7 @@ use crate::{
|
||||
cpu::{AtomicCpuSet, CpuId, CpuSet, PinCurrentCpu},
|
||||
prelude::*,
|
||||
sync::SpinLock,
|
||||
task::atomic_mode::AsAtomicModeGuard,
|
||||
};
|
||||
|
||||
/// A RCU monitor ensures the completion of _grace periods_ by keeping track
|
||||
@ -42,7 +43,7 @@ impl RcuMonitor {
|
||||
// GP.
|
||||
let callbacks = {
|
||||
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() {
|
||||
return;
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
#![expect(dead_code)]
|
||||
|
||||
use alloc::sync::Arc;
|
||||
use core::{
|
||||
cell::UnsafeCell,
|
||||
@ -15,9 +13,10 @@ use core::{
|
||||
};
|
||||
|
||||
use super::{
|
||||
guard::{GuardTransfer, Guardian},
|
||||
guard::{GuardTransfer, SpinGuardian},
|
||||
PreemptDisabled,
|
||||
};
|
||||
use crate::task::atomic_mode::AsAtomicModeGuard;
|
||||
|
||||
/// 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.
|
||||
///
|
||||
/// 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 + 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>
|
||||
{
|
||||
}
|
||||
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>
|
||||
{
|
||||
}
|
||||
|
||||
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>
|
||||
{
|
||||
}
|
||||
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>
|
||||
{
|
||||
}
|
||||
|
||||
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>
|
||||
{
|
||||
}
|
||||
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>
|
||||
{
|
||||
}
|
||||
@ -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.
|
||||
#[clippy::has_significant_drop]
|
||||
#[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,
|
||||
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`].
|
||||
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>`.
|
||||
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>
|
||||
{
|
||||
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>
|
||||
{
|
||||
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>
|
||||
{
|
||||
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.
|
||||
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,
|
||||
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`].
|
||||
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>`.
|
||||
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>
|
||||
{
|
||||
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.
|
||||
///
|
||||
/// 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>
|
||||
{
|
||||
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>
|
||||
{
|
||||
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>
|
||||
{
|
||||
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
|
||||
/// 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,
|
||||
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`].
|
||||
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>`.
|
||||
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>
|
||||
{
|
||||
/// 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>
|
||||
{
|
||||
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>
|
||||
{
|
||||
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>
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
|
@ -9,7 +9,8 @@ use core::{
|
||||
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.
|
||||
///
|
||||
@ -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.
|
||||
pub fn lock(&self) -> SpinLockGuard<T, G> {
|
||||
// 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.
|
||||
#[clippy::has_significant_drop]
|
||||
#[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,
|
||||
lock: R,
|
||||
}
|
||||
|
||||
impl<T: ?Sized, R: Deref<Target = SpinLock<T, G>>, G: Guardian> SpinLockGuard_<T, R, G> {
|
||||
/// Returns a reference to the guard.
|
||||
pub fn guard(&self) -> &G::Guard {
|
||||
&self.guard
|
||||
impl<T: ?Sized, R: Deref<Target = SpinLock<T, G>>, G: SpinGuardian> AsAtomicModeGuard
|
||||
for SpinLockGuard_<T, R, G>
|
||||
{
|
||||
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;
|
||||
|
||||
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>
|
||||
{
|
||||
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) {
|
||||
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>
|
||||
{
|
||||
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> {}
|
||||
|
||||
// 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
|
||||
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: SpinGuardian> Sync
|
||||
for SpinLockGuard_<T, R, G>
|
||||
{
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user