86 lines
2.1 KiB
Rust
86 lines
2.1 KiB
Rust
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<const T: bool> {}
|
|
pub trait IsTrue {}
|
|
impl IsTrue for Assert<true> {}
|
|
|
|
pub trait NonNullExt<T> {
|
|
unsafe fn add_ext(self, offset: usize) -> Self;
|
|
}
|
|
|
|
impl<T> NonNullExt<T> for NonNull<T> {
|
|
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<T: ?Sized> {
|
|
state: AtomicBool,
|
|
data: UnsafeCell<T>,
|
|
}
|
|
|
|
#[cfg(any(not(feature = "dep-of-kernel"), rust_analyzer))]
|
|
pub struct SpinlockGuard<'a, T: ?Sized> {
|
|
lock: &'a Spinlock<T>,
|
|
}
|
|
|
|
#[cfg(any(not(feature = "dep-of-kernel"), rust_analyzer))]
|
|
impl<T: ?Sized> Spinlock<T> {
|
|
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<T: ?Sized> Sync for Spinlock<T> {}
|