use core::ptr::NonNull; #[cfg(any(not(feature = "dep-of-kernel"), rust_analyzer))] use core::{ cell::UnsafeCell, ops::{Deref, DerefMut}, sync::atomic::{AtomicBool, Ordering}, }; pub enum Assert {} pub trait IsTrue {} impl IsTrue for Assert {} pub trait NonNullExt { unsafe fn add_ext(self, offset: usize) -> Self; } impl NonNullExt for NonNull { unsafe fn add_ext(self, offset: usize) -> Self { NonNull::new_unchecked(self.as_ptr().add(offset)) } } #[cfg(any(not(feature = "dep-of-kernel"), rust_analyzer))] pub struct Spinlock { state: AtomicBool, data: UnsafeCell, } #[cfg(any(not(feature = "dep-of-kernel"), rust_analyzer))] pub struct SpinlockGuard<'a, T: ?Sized> { lock: &'a Spinlock, } #[cfg(any(not(feature = "dep-of-kernel"), rust_analyzer))] impl Spinlock { pub const fn new(value: T) -> Self where T: Sized, { Self { state: AtomicBool::new(false), data: UnsafeCell::new(value), } } pub fn lock<'a>(&'a self) -> SpinlockGuard<'a, T> { while self .state .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed) .is_err() { core::hint::spin_loop(); } // Locked SpinlockGuard { lock: self } } } #[cfg(any(not(feature = "dep-of-kernel"), rust_analyzer))] impl<'a, T: ?Sized> Deref for SpinlockGuard<'a, T> { type Target = T; fn deref(&self) -> &Self::Target { unsafe { &*self.lock.data.get() } } } #[cfg(any(not(feature = "dep-of-kernel"), rust_analyzer))] impl<'a, T: ?Sized> DerefMut for SpinlockGuard<'a, T> { fn deref_mut(&mut self) -> &mut Self::Target { unsafe { &mut *self.lock.data.get() } } } #[cfg(any(not(feature = "dep-of-kernel"), rust_analyzer))] impl<'a, T: ?Sized> Drop for SpinlockGuard<'a, T> { fn drop(&mut self) { self.lock.state.store(false, Ordering::Release); } } #[cfg(any(not(feature = "dep-of-kernel"), rust_analyzer))] unsafe impl Sync for Spinlock {}