use core::{fmt, ptr};
use self::{
base::{BaseSpinLock, BaseSpinLockGuard},
rwlock::{BaseSpinRwLock, BaseSpinRwLockReadGuard, BaseSpinRwLockWriteGuard},
};
use super::context::{GuardState, PreemptIrqSaveState, PreemptState, RawState};
pub(crate) mod atomic;
mod base;
#[cfg(feature = "lockdep")]
pub(crate) mod lockdep;
mod raw;
mod rwlock;
pub use self::raw::RawIrqSaveMutex;
#[repr(transparent)]
pub struct RawSpinLock<T: ?Sized>(BaseSpinLock<RawState, T>);
pub type RawSpinLockGuard<'a, T> = BaseSpinLockGuard<'a, PreemptState, T>;
pub type RawSpinLockIrqSaveGuard<'a, T> = BaseSpinLockGuard<'a, PreemptIrqSaveState, T>;
pub type RawSpinLockUnpinnedGuard<'a, T> = BaseSpinLockGuard<'a, RawState, T>;
impl<T> RawSpinLock<T> {
#[inline(always)]
#[track_caller]
pub const fn new(data: T) -> Self {
Self(BaseSpinLock::new(data))
}
#[inline(always)]
pub fn into_inner(self) -> T {
self.0.into_inner()
}
}
impl<T: ?Sized> RawSpinLock<T> {
#[inline(always)]
fn with_state<G: GuardState>(&self) -> &BaseSpinLock<G, T> {
unsafe { &*(ptr::from_ref(&self.0) as *const BaseSpinLock<G, T>) }
}
#[inline(always)]
fn with_state_mut<G: GuardState>(&mut self) -> &mut BaseSpinLock<G, T> {
unsafe { &mut *(ptr::from_mut(&mut self.0) as *mut BaseSpinLock<G, T>) }
}
#[inline(always)]
#[track_caller]
pub fn lock(&self) -> RawSpinLockGuard<'_, T> {
self.with_state::<PreemptState>().lock()
}
#[inline(always)]
#[track_caller]
pub fn lock_nested(&self, subclass: u32) -> RawSpinLockGuard<'_, T> {
self.with_state::<PreemptState>().lock_nested(subclass)
}
#[inline(always)]
#[track_caller]
pub fn try_lock(&self) -> Option<RawSpinLockGuard<'_, T>> {
self.with_state::<PreemptState>().try_lock()
}
#[inline(always)]
#[track_caller]
pub fn lock_irqsave(&self) -> RawSpinLockIrqSaveGuard<'_, T> {
self.with_state::<PreemptIrqSaveState>().lock()
}
#[inline(always)]
#[track_caller]
pub fn lock_irqsave_nested(&self, subclass: u32) -> RawSpinLockIrqSaveGuard<'_, T> {
self.with_state::<PreemptIrqSaveState>()
.lock_nested(subclass)
}
#[inline(always)]
#[track_caller]
pub fn try_lock_irqsave(&self) -> Option<RawSpinLockIrqSaveGuard<'_, T>> {
self.with_state::<PreemptIrqSaveState>().try_lock()
}
#[inline(always)]
#[track_caller]
pub unsafe fn lock_raw(&self) -> RawSpinLockUnpinnedGuard<'_, T> {
self.with_state::<RawState>().lock()
}
#[inline(always)]
#[track_caller]
pub unsafe fn try_lock_raw(&self) -> Option<RawSpinLockUnpinnedGuard<'_, T>> {
self.with_state::<RawState>().try_lock()
}
#[inline(always)]
pub fn is_locked(&self) -> bool {
self.0.is_locked()
}
#[inline(always)]
pub fn get_mut(&mut self) -> &mut T {
self.with_state_mut::<RawState>().get_mut()
}
#[doc(hidden)]
#[inline(always)]
pub unsafe fn force_unlock(&self) {
unsafe { self.with_state::<PreemptState>().force_unlock() };
}
}
impl<T: Default> Default for RawSpinLock<T> {
fn default() -> Self {
Self::new(T::default())
}
}
impl<T: fmt::Debug> fmt::Debug for RawSpinLock<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.try_lock() {
Some(guard) => f
.debug_struct("RawSpinLock")
.field("data", &&*guard)
.finish(),
None => f
.debug_struct("RawSpinLock")
.field("data", &"<locked>")
.finish(),
}
}
}
#[repr(transparent)]
pub struct RawSpinRwLock<T: ?Sized>(BaseSpinRwLock<RawState, T>);
pub type RawSpinRwLockReadGuard<'a, T> = BaseSpinRwLockReadGuard<'a, PreemptState, T>;
pub type RawSpinRwLockWriteGuard<'a, T> = BaseSpinRwLockWriteGuard<'a, PreemptState, T>;
pub type RawSpinRwLockIrqSaveReadGuard<'a, T> = BaseSpinRwLockReadGuard<'a, PreemptIrqSaveState, T>;
pub type RawSpinRwLockIrqSaveWriteGuard<'a, T> =
BaseSpinRwLockWriteGuard<'a, PreemptIrqSaveState, T>;
pub type RawSpinRwLockUnpinnedReadGuard<'a, T> = BaseSpinRwLockReadGuard<'a, RawState, T>;
pub type RawSpinRwLockUnpinnedWriteGuard<'a, T> = BaseSpinRwLockWriteGuard<'a, RawState, T>;
impl<T> RawSpinRwLock<T> {
#[inline(always)]
#[track_caller]
pub const fn new(data: T) -> Self {
Self(BaseSpinRwLock::new(data))
}
#[inline(always)]
pub fn into_inner(self) -> T {
self.0.into_inner()
}
}
impl<T: ?Sized> RawSpinRwLock<T> {
#[inline(always)]
fn with_state<G: GuardState>(&self) -> &BaseSpinRwLock<G, T> {
unsafe { &*(ptr::from_ref(&self.0) as *const BaseSpinRwLock<G, T>) }
}
#[inline(always)]
fn with_state_mut<G: GuardState>(&mut self) -> &mut BaseSpinRwLock<G, T> {
unsafe { &mut *(ptr::from_mut(&mut self.0) as *mut BaseSpinRwLock<G, T>) }
}
#[inline(always)]
#[track_caller]
pub fn read(&self) -> RawSpinRwLockReadGuard<'_, T> {
self.with_state::<PreemptState>().read()
}
#[inline(always)]
#[track_caller]
pub fn try_read(&self) -> Option<RawSpinRwLockReadGuard<'_, T>> {
self.with_state::<PreemptState>().try_read()
}
#[inline(always)]
#[track_caller]
pub fn write(&self) -> RawSpinRwLockWriteGuard<'_, T> {
self.with_state::<PreemptState>().write()
}
#[inline(always)]
#[track_caller]
pub fn try_write(&self) -> Option<RawSpinRwLockWriteGuard<'_, T>> {
self.with_state::<PreemptState>().try_write()
}
#[inline(always)]
#[track_caller]
pub fn read_irqsave(&self) -> RawSpinRwLockIrqSaveReadGuard<'_, T> {
self.with_state::<PreemptIrqSaveState>().read()
}
#[inline(always)]
#[track_caller]
pub fn try_read_irqsave(&self) -> Option<RawSpinRwLockIrqSaveReadGuard<'_, T>> {
self.with_state::<PreemptIrqSaveState>().try_read()
}
#[inline(always)]
#[track_caller]
pub fn write_irqsave(&self) -> RawSpinRwLockIrqSaveWriteGuard<'_, T> {
self.with_state::<PreemptIrqSaveState>().write()
}
#[inline(always)]
#[track_caller]
pub fn try_write_irqsave(&self) -> Option<RawSpinRwLockIrqSaveWriteGuard<'_, T>> {
self.with_state::<PreemptIrqSaveState>().try_write()
}
#[inline(always)]
#[track_caller]
pub unsafe fn read_raw(&self) -> RawSpinRwLockUnpinnedReadGuard<'_, T> {
self.with_state::<RawState>().read()
}
#[inline(always)]
#[track_caller]
pub unsafe fn try_read_raw(&self) -> Option<RawSpinRwLockUnpinnedReadGuard<'_, T>> {
self.with_state::<RawState>().try_read()
}
#[inline(always)]
#[track_caller]
pub unsafe fn write_raw(&self) -> RawSpinRwLockUnpinnedWriteGuard<'_, T> {
self.with_state::<RawState>().write()
}
#[inline(always)]
#[track_caller]
pub unsafe fn try_write_raw(&self) -> Option<RawSpinRwLockUnpinnedWriteGuard<'_, T>> {
self.with_state::<RawState>().try_write()
}
#[inline(always)]
pub fn get_mut(&mut self) -> &mut T {
self.with_state_mut::<RawState>().get_mut()
}
#[doc(hidden)]
#[inline(always)]
pub unsafe fn force_read_decrement_raw(&self) {
unsafe {
self.with_state::<RawState>().force_read_decrement();
}
}
}
impl<T: Default> Default for RawSpinRwLock<T> {
fn default() -> Self {
Self::new(T::default())
}
}
impl<T> From<T> for RawSpinRwLock<T> {
fn from(value: T) -> Self {
Self::new(value)
}
}
impl<T: fmt::Debug> fmt::Debug for RawSpinRwLock<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.try_read() {
Some(guard) => f
.debug_struct("RawSpinRwLock")
.field("data", &&*guard)
.finish(),
None => f
.debug_struct("RawSpinRwLock")
.field("data", &"<write locked>")
.finish(),
}
}
}