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 RawSpinLock<T: ?Sized>(BaseSpinLock<RawState, T>);
27
28pub type RawSpinLockGuard<'a, T> = BaseSpinLockGuard<'a, PreemptState, T>;
30
31pub type RawSpinLockIrqSaveGuard<'a, T> = BaseSpinLockGuard<'a, PreemptIrqSaveState, T>;
33
34pub type RawSpinLockUnpinnedGuard<'a, T> = BaseSpinLockGuard<'a, RawState, T>;
36
37impl<T> RawSpinLock<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> RawSpinLock<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) -> RawSpinLockGuard<'_, T> {
72 self.with_state::<PreemptState>().lock()
73 }
74
75 #[inline(always)]
80 #[track_caller]
81 pub fn lock_nested(&self, subclass: u32) -> RawSpinLockGuard<'_, T> {
82 self.with_state::<PreemptState>().lock_nested(subclass)
83 }
84
85 #[inline(always)]
87 #[track_caller]
88 pub fn try_lock(&self) -> Option<RawSpinLockGuard<'_, T>> {
89 self.with_state::<PreemptState>().try_lock()
90 }
91
92 #[inline(always)]
94 #[track_caller]
95 pub fn lock_irqsave(&self) -> RawSpinLockIrqSaveGuard<'_, T> {
96 self.with_state::<PreemptIrqSaveState>().lock()
97 }
98
99 #[inline(always)]
105 #[track_caller]
106 pub fn lock_irqsave_nested(&self, subclass: u32) -> RawSpinLockIrqSaveGuard<'_, 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<RawSpinLockIrqSaveGuard<'_, T>> {
115 self.with_state::<PreemptIrqSaveState>().try_lock()
116 }
117
118 #[inline(always)]
126 #[track_caller]
127 pub unsafe fn lock_raw(&self) -> RawSpinLockUnpinnedGuard<'_, T> {
128 self.with_state::<RawState>().lock()
129 }
130
131 #[inline(always)]
138 #[track_caller]
139 pub unsafe fn try_lock_raw(&self) -> Option<RawSpinLockUnpinnedGuard<'_, 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 RawSpinLock<T> {
171 fn default() -> Self {
172 Self::new(T::default())
173 }
174}
175
176impl<T: fmt::Debug> fmt::Debug for RawSpinLock<T> {
177 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
178 match self.try_lock() {
179 Some(guard) => f
180 .debug_struct("RawSpinLock")
181 .field("data", &&*guard)
182 .finish(),
183 None => f
184 .debug_struct("RawSpinLock")
185 .field("data", &"<locked>")
186 .finish(),
187 }
188 }
189}
190
191#[repr(transparent)]
193pub struct RawSpinRwLock<T: ?Sized>(BaseSpinRwLock<RawState, T>);
194
195pub type RawSpinRwLockReadGuard<'a, T> = BaseSpinRwLockReadGuard<'a, PreemptState, T>;
197
198pub type RawSpinRwLockWriteGuard<'a, T> = BaseSpinRwLockWriteGuard<'a, PreemptState, T>;
200
201pub type RawSpinRwLockIrqSaveReadGuard<'a, T> = BaseSpinRwLockReadGuard<'a, PreemptIrqSaveState, T>;
203
204pub type RawSpinRwLockIrqSaveWriteGuard<'a, T> =
206 BaseSpinRwLockWriteGuard<'a, PreemptIrqSaveState, T>;
207
208pub type RawSpinRwLockUnpinnedReadGuard<'a, T> = BaseSpinRwLockReadGuard<'a, RawState, T>;
210
211pub type RawSpinRwLockUnpinnedWriteGuard<'a, T> = BaseSpinRwLockWriteGuard<'a, RawState, T>;
213
214impl<T> RawSpinRwLock<T> {
215 #[inline(always)]
217 #[track_caller]
218 pub const fn new(data: T) -> Self {
219 Self(BaseSpinRwLock::new(data))
220 }
221
222 #[inline(always)]
224 pub fn into_inner(self) -> T {
225 self.0.into_inner()
226 }
227}
228
229impl<T: ?Sized> RawSpinRwLock<T> {
230 #[inline(always)]
231 fn with_state<G: GuardState>(&self) -> &BaseSpinRwLock<G, T> {
232 unsafe { &*(ptr::from_ref(&self.0) as *const BaseSpinRwLock<G, T>) }
235 }
236
237 #[inline(always)]
238 fn with_state_mut<G: GuardState>(&mut self) -> &mut BaseSpinRwLock<G, T> {
239 unsafe { &mut *(ptr::from_mut(&mut self.0) as *mut BaseSpinRwLock<G, T>) }
241 }
242
243 #[inline(always)]
245 #[track_caller]
246 pub fn read(&self) -> RawSpinRwLockReadGuard<'_, T> {
247 self.with_state::<PreemptState>().read()
248 }
249
250 #[inline(always)]
252 #[track_caller]
253 pub fn try_read(&self) -> Option<RawSpinRwLockReadGuard<'_, T>> {
254 self.with_state::<PreemptState>().try_read()
255 }
256
257 #[inline(always)]
259 #[track_caller]
260 pub fn write(&self) -> RawSpinRwLockWriteGuard<'_, T> {
261 self.with_state::<PreemptState>().write()
262 }
263
264 #[inline(always)]
266 #[track_caller]
267 pub fn try_write(&self) -> Option<RawSpinRwLockWriteGuard<'_, T>> {
268 self.with_state::<PreemptState>().try_write()
269 }
270
271 #[inline(always)]
273 #[track_caller]
274 pub fn read_irqsave(&self) -> RawSpinRwLockIrqSaveReadGuard<'_, T> {
275 self.with_state::<PreemptIrqSaveState>().read()
276 }
277
278 #[inline(always)]
280 #[track_caller]
281 pub fn try_read_irqsave(&self) -> Option<RawSpinRwLockIrqSaveReadGuard<'_, T>> {
282 self.with_state::<PreemptIrqSaveState>().try_read()
283 }
284
285 #[inline(always)]
287 #[track_caller]
288 pub fn write_irqsave(&self) -> RawSpinRwLockIrqSaveWriteGuard<'_, T> {
289 self.with_state::<PreemptIrqSaveState>().write()
290 }
291
292 #[inline(always)]
294 #[track_caller]
295 pub fn try_write_irqsave(&self) -> Option<RawSpinRwLockIrqSaveWriteGuard<'_, T>> {
296 self.with_state::<PreemptIrqSaveState>().try_write()
297 }
298
299 #[inline(always)]
306 #[track_caller]
307 pub unsafe fn read_raw(&self) -> RawSpinRwLockUnpinnedReadGuard<'_, T> {
308 self.with_state::<RawState>().read()
309 }
310
311 #[inline(always)]
317 #[track_caller]
318 pub unsafe fn try_read_raw(&self) -> Option<RawSpinRwLockUnpinnedReadGuard<'_, T>> {
319 self.with_state::<RawState>().try_read()
320 }
321
322 #[inline(always)]
329 #[track_caller]
330 pub unsafe fn write_raw(&self) -> RawSpinRwLockUnpinnedWriteGuard<'_, T> {
331 self.with_state::<RawState>().write()
332 }
333
334 #[inline(always)]
340 #[track_caller]
341 pub unsafe fn try_write_raw(&self) -> Option<RawSpinRwLockUnpinnedWriteGuard<'_, T>> {
342 self.with_state::<RawState>().try_write()
343 }
344
345 #[inline(always)]
347 pub fn get_mut(&mut self) -> &mut T {
348 self.with_state_mut::<RawState>().get_mut()
349 }
350
351 #[doc(hidden)]
358 #[inline(always)]
359 pub unsafe fn force_read_decrement_raw(&self) {
360 unsafe {
361 self.with_state::<RawState>().force_read_decrement();
362 }
363 }
364}
365
366impl<T: Default> Default for RawSpinRwLock<T> {
367 fn default() -> Self {
368 Self::new(T::default())
369 }
370}
371
372impl<T> From<T> for RawSpinRwLock<T> {
373 fn from(value: T) -> Self {
374 Self::new(value)
375 }
376}
377
378impl<T: fmt::Debug> fmt::Debug for RawSpinRwLock<T> {
379 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
380 match self.try_read() {
381 Some(guard) => f
382 .debug_struct("RawSpinRwLock")
383 .field("data", &&*guard)
384 .finish(),
385 None => f
386 .debug_struct("RawSpinRwLock")
387 .field("data", &"<write locked>")
388 .finish(),
389 }
390 }
391}