rustubs/proc/sync/
spin.rs1use crate::arch::x86_64::interrupt::{irq_restore, irq_save};
10use core::ops::{Deref, DerefMut};
11
12pub struct SpinMutexIRQ<T: ?Sized> {
14 inner: spin::Mutex<T>,
15}
16
17pub struct SpinMutexIRQGuard<'a, T: ?Sized + 'a> {
18 spin_guard: Option<spin::MutexGuard<'a, T>>,
19 irq_was_enabled: bool,
20}
21
22unsafe impl<T: ?Sized> Send for SpinMutexIRQ<T> {}
24unsafe impl<T: ?Sized> Sync for SpinMutexIRQ<T> {}
25
26impl<T> SpinMutexIRQ<T> {
27 pub const fn new(data: T) -> Self { Self { inner: spin::Mutex::new(data) } }
28 pub fn into_inner(self) -> T { self.inner.into_inner() }
29}
30
31impl<T: ?Sized> SpinMutexIRQ<T> {
32 #[inline]
33 pub fn lock(&self) -> SpinMutexIRQGuard<'_, T> {
34 let irq_was_enabled = irq_save();
36 let spin_guard = self.inner.lock();
37 SpinMutexIRQGuard {
38 spin_guard: Some(spin_guard),
39 irq_was_enabled,
40 }
41 }
42}
43
44impl<T: ?Sized> Drop for SpinMutexIRQGuard<'_, T> {
45 fn drop(&mut self) {
46 self.spin_guard.take();
47 irq_restore(self.irq_was_enabled);
48 }
49}
50
51impl<T: ?Sized> Deref for SpinMutexIRQGuard<'_, T> {
52 type Target = T;
53 fn deref(&self) -> &T { self.spin_guard.as_ref().expect("guard taken") }
54}
55
56impl<T: ?Sized> DerefMut for SpinMutexIRQGuard<'_, T> {
57 fn deref_mut(&mut self) -> &mut T {
58 self.spin_guard.as_mut().expect("guard taken")
59 }
60}