guard.rs 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. use super::{Relax, Spin, SpinRelax};
  2. use crate::{marker::NotSend, ForceUnlockableGuard, UnlockableGuard, UnlockedGuard};
  3. use core::{
  4. marker::PhantomData,
  5. mem::ManuallyDrop,
  6. ops::{Deref, DerefMut},
  7. };
  8. pub struct SpinGuard<'a, T, R = SpinRelax>
  9. where
  10. T: ?Sized,
  11. {
  12. pub(super) lock: &'a Spin<T, R>,
  13. pub(super) value: &'a mut T,
  14. /// We don't want this to be `Send` because we don't want to allow the guard to be
  15. /// transferred to another thread since we have disabled the preemption on the local cpu.
  16. pub(super) _not_send: PhantomData<NotSend>,
  17. }
  18. pub struct SpinIrqGuard<'a, T, R = SpinRelax>
  19. where
  20. T: ?Sized,
  21. {
  22. pub(super) lock: &'a Spin<T, R>,
  23. pub(super) value: &'a mut T,
  24. pub(super) irq_state: ManuallyDrop<arch::IrqState>,
  25. /// We don't want this to be `Send` because we don't want to allow the guard to be
  26. /// transferred to another thread since we have disabled the preemption and saved
  27. /// IRQ states on the local cpu.
  28. pub(super) _not_send: PhantomData<NotSend>,
  29. }
  30. pub struct UnlockedSpinGuard<'a, T, R>(&'a Spin<T, R>)
  31. where
  32. T: ?Sized;
  33. pub struct UnlockedSpinIrqGuard<'a, T, R>
  34. where
  35. T: ?Sized,
  36. {
  37. lock: &'a Spin<T, R>,
  38. irq_state: arch::IrqState,
  39. }
  40. // SAFETY: As long as the value protected by the lock is able to be shared between threads,
  41. // we can access the guard from multiple threads.
  42. unsafe impl<T, R> Sync for SpinGuard<'_, T, R> where T: ?Sized + Sync {}
  43. // SAFETY: As long as the value protected by the lock is able to be shared between threads,
  44. // we can access the guard from multiple threads.
  45. unsafe impl<T, R> Sync for SpinIrqGuard<'_, T, R> where T: ?Sized + Sync {}
  46. impl<T, R> Drop for SpinGuard<'_, T, R>
  47. where
  48. T: ?Sized,
  49. {
  50. fn drop(&mut self) {
  51. unsafe {
  52. // SAFETY: We are dropping the guard, so we are not holding the lock anymore.
  53. self.lock.do_unlock();
  54. }
  55. }
  56. }
  57. impl<T, R> Drop for SpinIrqGuard<'_, T, R>
  58. where
  59. T: ?Sized,
  60. {
  61. fn drop(&mut self) {
  62. unsafe {
  63. // SAFETY: We are dropping the guard, so we are not holding the lock anymore.
  64. self.lock.do_unlock();
  65. // SAFETY: We are dropping the guard, so we are never going to access the value.
  66. ManuallyDrop::take(&mut self.irq_state).restore();
  67. }
  68. }
  69. }
  70. impl<T, R> Deref for SpinGuard<'_, T, R>
  71. where
  72. T: ?Sized,
  73. {
  74. type Target = T;
  75. fn deref(&self) -> &Self::Target {
  76. // SAFETY: We are holding the lock, so we can safely access the value.
  77. self.value
  78. }
  79. }
  80. impl<T, R> DerefMut for SpinGuard<'_, T, R>
  81. where
  82. T: ?Sized,
  83. {
  84. fn deref_mut(&mut self) -> &mut Self::Target {
  85. // SAFETY: We are holding the lock, so we can safely access the value.
  86. self.value
  87. }
  88. }
  89. impl<T, U, R> AsRef<U> for SpinGuard<'_, T, R>
  90. where
  91. T: ?Sized,
  92. U: ?Sized,
  93. <Self as Deref>::Target: AsRef<U>,
  94. {
  95. fn as_ref(&self) -> &U {
  96. self.deref().as_ref()
  97. }
  98. }
  99. impl<T, U, R> AsMut<U> for SpinGuard<'_, T, R>
  100. where
  101. T: ?Sized,
  102. U: ?Sized,
  103. <Self as Deref>::Target: AsMut<U>,
  104. {
  105. fn as_mut(&mut self) -> &mut U {
  106. self.deref_mut().as_mut()
  107. }
  108. }
  109. impl<T, R> Deref for SpinIrqGuard<'_, T, R>
  110. where
  111. T: ?Sized,
  112. {
  113. type Target = T;
  114. fn deref(&self) -> &Self::Target {
  115. // SAFETY: We are holding the lock, so we can safely access the value.
  116. self.value
  117. }
  118. }
  119. impl<T, R> DerefMut for SpinIrqGuard<'_, T, R>
  120. where
  121. T: ?Sized,
  122. {
  123. fn deref_mut(&mut self) -> &mut Self::Target {
  124. // SAFETY: We are holding the lock, so we can safely access the value.
  125. self.value
  126. }
  127. }
  128. impl<T, U, R> AsRef<U> for SpinIrqGuard<'_, T, R>
  129. where
  130. T: ?Sized,
  131. U: ?Sized,
  132. <Self as Deref>::Target: AsRef<U>,
  133. {
  134. fn as_ref(&self) -> &U {
  135. self.deref().as_ref()
  136. }
  137. }
  138. impl<T, U, R> AsMut<U> for SpinIrqGuard<'_, T, R>
  139. where
  140. T: ?Sized,
  141. U: ?Sized,
  142. <Self as Deref>::Target: AsMut<U>,
  143. {
  144. fn as_mut(&mut self) -> &mut U {
  145. self.deref_mut().as_mut()
  146. }
  147. }
  148. impl<'a, T, R> UnlockableGuard for SpinGuard<'a, T, R>
  149. where
  150. T: ?Sized,
  151. R: Relax,
  152. {
  153. type Unlocked = UnlockedSpinGuard<'a, T, R>;
  154. fn unlock(self) -> Self::Unlocked {
  155. let me = ManuallyDrop::new(self);
  156. unsafe {
  157. // SAFETY: No access is possible after unlocking.
  158. me.lock.do_unlock();
  159. }
  160. UnlockedSpinGuard(me.lock)
  161. }
  162. }
  163. impl<'a, T, R> UnlockableGuard for SpinIrqGuard<'a, T, R>
  164. where
  165. T: ?Sized,
  166. R: Relax,
  167. {
  168. type Unlocked = UnlockedSpinIrqGuard<'a, T, R>;
  169. fn unlock(self) -> Self::Unlocked {
  170. let mut me = ManuallyDrop::new(self);
  171. unsafe {
  172. // SAFETY: No access is possible after unlocking.
  173. me.lock.do_unlock();
  174. }
  175. UnlockedSpinIrqGuard {
  176. lock: me.lock,
  177. // SAFETY: `me` is going to be dropped so never used again.
  178. irq_state: unsafe { ManuallyDrop::take(&mut me.irq_state) },
  179. }
  180. }
  181. }
  182. // SAFETY: The guard is stateless so no more process needed.
  183. unsafe impl<'a, T, R> UnlockedGuard for UnlockedSpinGuard<'a, T, R>
  184. where
  185. T: ?Sized,
  186. R: Relax,
  187. {
  188. type Guard = SpinGuard<'a, T, R>;
  189. fn relock(self) -> Self::Guard {
  190. let Self(lock) = self;
  191. lock.lock()
  192. }
  193. }
  194. // SAFETY: The guard is stateless so no more process needed.
  195. unsafe impl<'a, T, R> UnlockedGuard for UnlockedSpinIrqGuard<'a, T, R>
  196. where
  197. T: ?Sized,
  198. R: Relax,
  199. {
  200. type Guard = SpinIrqGuard<'a, T, R>;
  201. fn relock(self) -> Self::Guard {
  202. let mut guard = self.lock.lock_irq();
  203. guard.irq_state = ManuallyDrop::new(self.irq_state);
  204. guard
  205. }
  206. }
  207. impl<'a, T, R> ForceUnlockableGuard for SpinGuard<'a, T, R>
  208. where
  209. T: ?Sized,
  210. R: Relax,
  211. {
  212. unsafe fn force_unlock(&mut self) {
  213. unsafe {
  214. // SAFETY: The caller assures that the value is no longer accessed.
  215. self.lock.do_unlock();
  216. }
  217. }
  218. unsafe fn force_relock(&mut self) {
  219. self.lock.do_lock();
  220. }
  221. }
  222. impl<'a, T, R> ForceUnlockableGuard for SpinIrqGuard<'a, T, R>
  223. where
  224. T: ?Sized,
  225. R: Relax,
  226. {
  227. unsafe fn force_unlock(&mut self) {
  228. unsafe {
  229. // SAFETY: The caller assures that the value is no longer accessed.
  230. self.lock.do_unlock();
  231. }
  232. // IRQ state is not restored.
  233. }
  234. unsafe fn force_relock(&mut self) {
  235. self.lock.do_lock();
  236. }
  237. }