1use core::{fmt, ptr};
4
5use self::{
6 base::{BaseSpinLock, BaseSpinLockGuard},
7 rwlock::{BaseSpinRwLock, BaseSpinRwLockReadGuard, BaseSpinRwLockWriteGuard},
8};
9use super::context::{GuardState, PreemptIrqSaveState, PreemptState, RawState};
10
11pub(crate) mod atomic;
12mod base;
13#[cfg(feature = "lockdep")]
14pub(crate) mod lockdep;
15mod raw;
16mod rwlock;
17
18pub use self::raw::RawIrqSaveMutex;
19
20#[repr(transparent)]
26pub struct SpinLock<T: ?Sized>(BaseSpinLock<RawState, T>);
27
28pub type SpinLockGuard<'a, T> = BaseSpinLockGuard<'a, PreemptState, T>;
30
31pub type SpinLockIrqSaveGuard<'a, T> = BaseSpinLockGuard<'a, PreemptIrqSaveState, T>;
33
34pub type RawSpinLockGuard<'a, T> = BaseSpinLockGuard<'a, RawState, T>;
36
37impl<T> SpinLock<T> {
38 #[inline(always)]
40 #[track_caller]
41 pub const fn new(data: T) -> Self {
42 Self(BaseSpinLock::new(data))
43 }
44
45 #[inline(always)]
47 pub fn into_inner(self) -> T {
48 self.0.into_inner()
49 }
50}
51
52impl<T: ?Sized> SpinLock<T> {
53 #[inline(always)]
54 fn with_state<G: GuardState>(&self) -> &BaseSpinLock<G, T> {
55 unsafe { &*(ptr::from_ref(&self.0) as *const BaseSpinLock<G, T>) }
60 }
61
62 #[inline(always)]
63 fn with_state_mut<G: GuardState>(&mut self) -> &mut BaseSpinLock<G, T> {
64 unsafe { &mut *(ptr::from_mut(&mut self.0) as *mut BaseSpinLock<G, T>) }
66 }
67
68 #[inline(always)]
70 #[track_caller]
71 pub fn lock(&self) -> SpinLockGuard<'_, T> {
72 self.with_state::<PreemptState>().lock()
73 }
74
75 #[inline(always)]
80 #[track_caller]
81 pub fn lock_nested(&self, subclass: u32) -> SpinLockGuard<'_, T> {
82 self.with_state::<PreemptState>().lock_nested(subclass)
83 }
84
85 #[inline(always)]
87 #[track_caller]
88 pub fn try_lock(&self) -> Option<SpinLockGuard<'_, T>> {
89 self.with_state::<PreemptState>().try_lock()
90 }
91
92 #[inline(always)]
94 #[track_caller]
95 pub fn lock_irqsave(&self) -> SpinLockIrqSaveGuard<'_, T> {
96 self.with_state::<PreemptIrqSaveState>().lock()
97 }
98
99 #[inline(always)]
105 #[track_caller]
106 pub fn lock_irqsave_nested(&self, subclass: u32) -> SpinLockIrqSaveGuard<'_, T> {
107 self.with_state::<PreemptIrqSaveState>()
108 .lock_nested(subclass)
109 }
110
111 #[inline(always)]
113 #[track_caller]
114 pub fn try_lock_irqsave(&self) -> Option<SpinLockIrqSaveGuard<'_, T>> {
115 self.with_state::<PreemptIrqSaveState>().try_lock()
116 }
117
118 #[inline(always)]
126 #[track_caller]
127 pub unsafe fn lock_raw(&self) -> RawSpinLockGuard<'_, T> {
128 self.with_state::<RawState>().lock()
129 }
130
131 #[inline(always)]
138 #[track_caller]
139 pub unsafe fn try_lock_raw(&self) -> Option<RawSpinLockGuard<'_, T>> {
140 self.with_state::<RawState>().try_lock()
141 }
142
143 #[inline(always)]
147 pub fn is_locked(&self) -> bool {
148 self.0.is_locked()
149 }
150
151 #[inline(always)]
153 pub fn get_mut(&mut self) -> &mut T {
154 self.with_state_mut::<RawState>().get_mut()
155 }
156
157 #[doc(hidden)]
164 #[inline(always)]
165 pub unsafe fn force_unlock(&self) {
166 unsafe { self.with_state::<PreemptState>().force_unlock() };
167 }
168}
169
170impl<T: Default> Default for SpinLock<T> {
171 fn default() -> Self {
172 Self::new(T::default())
173 }
174}
175
176impl<T: fmt::Debug> fmt::Debug for SpinLock<T> {
177 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
178 match self.try_lock() {
179 Some(guard) => f.debug_struct("SpinLock").field("data", &&*guard).finish(),
180 None => f
181 .debug_struct("SpinLock")
182 .field("data", &"<locked>")
183 .finish(),
184 }
185 }
186}
187
188#[repr(transparent)]
190pub struct SpinRwLock<T: ?Sized>(BaseSpinRwLock<RawState, T>);
191
192pub type SpinRwLockReadGuard<'a, T> = BaseSpinRwLockReadGuard<'a, PreemptState, T>;
194
195pub type SpinRwLockWriteGuard<'a, T> = BaseSpinRwLockWriteGuard<'a, PreemptState, T>;
197
198pub type SpinRwLockIrqSaveReadGuard<'a, T> = BaseSpinRwLockReadGuard<'a, PreemptIrqSaveState, T>;
200
201pub type SpinRwLockIrqSaveWriteGuard<'a, T> = BaseSpinRwLockWriteGuard<'a, PreemptIrqSaveState, T>;
203
204pub type RawSpinRwLockReadGuard<'a, T> = BaseSpinRwLockReadGuard<'a, RawState, T>;
206
207pub type RawSpinRwLockWriteGuard<'a, T> = BaseSpinRwLockWriteGuard<'a, RawState, T>;
209
210impl<T> SpinRwLock<T> {
211 #[inline(always)]
213 #[track_caller]
214 pub const fn new(data: T) -> Self {
215 Self(BaseSpinRwLock::new(data))
216 }
217
218 #[inline(always)]
220 pub fn into_inner(self) -> T {
221 self.0.into_inner()
222 }
223}
224
225impl<T: ?Sized> SpinRwLock<T> {
226 #[inline(always)]
227 fn with_state<G: GuardState>(&self) -> &BaseSpinRwLock<G, T> {
228 unsafe { &*(ptr::from_ref(&self.0) as *const BaseSpinRwLock<G, T>) }
231 }
232
233 #[inline(always)]
234 fn with_state_mut<G: GuardState>(&mut self) -> &mut BaseSpinRwLock<G, T> {
235 unsafe { &mut *(ptr::from_mut(&mut self.0) as *mut BaseSpinRwLock<G, T>) }
237 }
238
239 #[inline(always)]
241 #[track_caller]
242 pub fn read(&self) -> SpinRwLockReadGuard<'_, T> {
243 self.with_state::<PreemptState>().read()
244 }
245
246 #[inline(always)]
248 #[track_caller]
249 pub fn try_read(&self) -> Option<SpinRwLockReadGuard<'_, T>> {
250 self.with_state::<PreemptState>().try_read()
251 }
252
253 #[inline(always)]
255 #[track_caller]
256 pub fn write(&self) -> SpinRwLockWriteGuard<'_, T> {
257 self.with_state::<PreemptState>().write()
258 }
259
260 #[inline(always)]
262 #[track_caller]
263 pub fn try_write(&self) -> Option<SpinRwLockWriteGuard<'_, T>> {
264 self.with_state::<PreemptState>().try_write()
265 }
266
267 #[inline(always)]
269 #[track_caller]
270 pub fn read_irqsave(&self) -> SpinRwLockIrqSaveReadGuard<'_, T> {
271 self.with_state::<PreemptIrqSaveState>().read()
272 }
273
274 #[inline(always)]
276 #[track_caller]
277 pub fn try_read_irqsave(&self) -> Option<SpinRwLockIrqSaveReadGuard<'_, T>> {
278 self.with_state::<PreemptIrqSaveState>().try_read()
279 }
280
281 #[inline(always)]
283 #[track_caller]
284 pub fn write_irqsave(&self) -> SpinRwLockIrqSaveWriteGuard<'_, T> {
285 self.with_state::<PreemptIrqSaveState>().write()
286 }
287
288 #[inline(always)]
290 #[track_caller]
291 pub fn try_write_irqsave(&self) -> Option<SpinRwLockIrqSaveWriteGuard<'_, T>> {
292 self.with_state::<PreemptIrqSaveState>().try_write()
293 }
294
295 #[inline(always)]
302 #[track_caller]
303 pub unsafe fn read_raw(&self) -> RawSpinRwLockReadGuard<'_, T> {
304 self.with_state::<RawState>().read()
305 }
306
307 #[inline(always)]
313 #[track_caller]
314 pub unsafe fn try_read_raw(&self) -> Option<RawSpinRwLockReadGuard<'_, T>> {
315 self.with_state::<RawState>().try_read()
316 }
317
318 #[inline(always)]
325 #[track_caller]
326 pub unsafe fn write_raw(&self) -> RawSpinRwLockWriteGuard<'_, T> {
327 self.with_state::<RawState>().write()
328 }
329
330 #[inline(always)]
336 #[track_caller]
337 pub unsafe fn try_write_raw(&self) -> Option<RawSpinRwLockWriteGuard<'_, T>> {
338 self.with_state::<RawState>().try_write()
339 }
340
341 #[inline(always)]
343 pub fn get_mut(&mut self) -> &mut T {
344 self.with_state_mut::<RawState>().get_mut()
345 }
346
347 #[doc(hidden)]
354 #[inline(always)]
355 pub unsafe fn force_read_decrement_raw(&self) {
356 unsafe {
357 self.with_state::<RawState>().force_read_decrement();
358 }
359 }
360}
361
362impl<T: Default> Default for SpinRwLock<T> {
363 fn default() -> Self {
364 Self::new(T::default())
365 }
366}
367
368impl<T> From<T> for SpinRwLock<T> {
369 fn from(value: T) -> Self {
370 Self::new(value)
371 }
372}
373
374impl<T: fmt::Debug> fmt::Debug for SpinRwLock<T> {
375 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
376 match self.try_read() {
377 Some(guard) => f
378 .debug_struct("SpinRwLock")
379 .field("data", &&*guard)
380 .finish(),
381 None => f
382 .debug_struct("SpinRwLock")
383 .field("data", &"<write locked>")
384 .finish(),
385 }
386 }
387}