lock.rs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. use core::{
  2. cell::UnsafeCell,
  3. ops::{Deref, DerefMut},
  4. };
  5. use super::{
  6. semaphore::{RwSemaphoreStrategy, SemaphoreStrategy},
  7. spin::IrqStrategy,
  8. strategy::LockStrategy,
  9. RwSemWriteGuard, SemGuard,
  10. };
  11. pub struct Lock<Value: ?Sized, Strategy: LockStrategy> {
  12. strategy_data: Strategy::StrategyData,
  13. value: UnsafeCell<Value>,
  14. }
  15. unsafe impl<T: ?Sized + Send, S: LockStrategy> Send for Lock<T, S> {}
  16. unsafe impl<T: ?Sized + Send, S: LockStrategy> Sync for Lock<T, S> {}
  17. impl<Value, Strategy: LockStrategy> Lock<Value, Strategy> {
  18. #[inline(always)]
  19. pub fn new(value: Value) -> Self {
  20. Self {
  21. strategy_data: Strategy::data(),
  22. value: UnsafeCell::new(value),
  23. }
  24. }
  25. }
  26. impl<Value: core::fmt::Debug, Strategy: LockStrategy> core::fmt::Debug for Lock<Value, Strategy> {
  27. fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
  28. f.debug_struct("Lock")
  29. .field("locked_value", &self.value)
  30. .finish()
  31. }
  32. }
  33. impl<Value: Clone, Strategy: LockStrategy> Clone for Lock<Value, Strategy> {
  34. fn clone(&self) -> Self {
  35. Self {
  36. strategy_data: Strategy::data(),
  37. value: UnsafeCell::new(self.lock_shared().clone()),
  38. }
  39. }
  40. }
  41. impl<Value: Default, Strategy: LockStrategy> Default for Lock<Value, Strategy> {
  42. fn default() -> Self {
  43. Self {
  44. strategy_data: Strategy::data(),
  45. value: Default::default(),
  46. }
  47. }
  48. }
  49. #[allow(dead_code)]
  50. impl<Value: ?Sized> Lock<Value, SemaphoreStrategy> {
  51. #[inline(always)]
  52. pub fn lock_nosleep(&self) -> SemGuard<'_, Value> {
  53. loop {
  54. if !self.is_locked() {
  55. if let Some(guard) = self.try_lock() {
  56. return guard;
  57. }
  58. }
  59. arch::pause();
  60. }
  61. }
  62. }
  63. impl<Value: ?Sized> Lock<Value, RwSemaphoreStrategy> {
  64. #[inline(always)]
  65. pub fn lock_nosleep(&self) -> RwSemWriteGuard<'_, Value> {
  66. loop {
  67. if self.is_locked() {
  68. if let Some(guard) = self.try_lock() {
  69. return guard;
  70. }
  71. }
  72. arch::pause();
  73. }
  74. }
  75. }
  76. #[allow(dead_code)]
  77. impl<Value: ?Sized, Strategy: LockStrategy> Lock<Value, Strategy> {
  78. #[inline(always)]
  79. pub fn is_locked(&self) -> bool {
  80. unsafe { Strategy::is_locked(&self.strategy_data) }
  81. }
  82. #[inline(always)]
  83. pub fn try_lock<'lt>(&'lt self) -> Option<Guard<'lt, Value, Strategy>> {
  84. if unsafe { Strategy::is_locked(&self.strategy_data) } {
  85. return None;
  86. }
  87. unsafe { Strategy::try_lock(&self.strategy_data) }.map(|context| Guard {
  88. _phantom: core::marker::PhantomData,
  89. value: &self.value,
  90. strategy_data: &self.strategy_data,
  91. context,
  92. })
  93. }
  94. #[inline(always)]
  95. pub fn lock<'lt>(&'lt self) -> Guard<'lt, Value, Strategy> {
  96. Guard {
  97. _phantom: core::marker::PhantomData,
  98. value: &self.value,
  99. strategy_data: &self.strategy_data,
  100. context: unsafe { Strategy::do_lock(&self.strategy_data) },
  101. }
  102. }
  103. #[inline(always)]
  104. pub fn lock_irq<'lt>(&'lt self) -> Guard<'lt, Value, IrqStrategy<Strategy>> {
  105. Guard {
  106. _phantom: core::marker::PhantomData,
  107. value: &self.value,
  108. strategy_data: &self.strategy_data,
  109. context: unsafe { IrqStrategy::<Strategy>::do_lock(&self.strategy_data) },
  110. }
  111. }
  112. #[inline(always)]
  113. pub fn lock_shared<'lt>(&'lt self) -> Guard<'lt, Value, Strategy, false> {
  114. Guard {
  115. _phantom: core::marker::PhantomData,
  116. value: &self.value,
  117. strategy_data: &self.strategy_data,
  118. context: unsafe { Strategy::do_lock_shared(&self.strategy_data) },
  119. }
  120. }
  121. #[inline(always)]
  122. pub fn lock_shared_irq<'lt>(&'lt self) -> Guard<'lt, Value, IrqStrategy<Strategy>, false> {
  123. Guard {
  124. _phantom: core::marker::PhantomData,
  125. value: &self.value,
  126. strategy_data: &self.strategy_data,
  127. context: unsafe { IrqStrategy::<Strategy>::do_lock(&self.strategy_data) },
  128. }
  129. }
  130. #[inline(always)]
  131. pub fn get_mut(&mut self) -> &mut Value {
  132. unsafe { &mut *self.value.get() }
  133. }
  134. }
  135. pub struct Guard<'lock, Value: ?Sized, Strategy: LockStrategy, const WRITE: bool = true> {
  136. _phantom: core::marker::PhantomData<Strategy>,
  137. value: &'lock UnsafeCell<Value>,
  138. strategy_data: &'lock Strategy::StrategyData,
  139. context: Strategy::GuardContext,
  140. }
  141. impl<'lock, Value: ?Sized, Strategy: LockStrategy, const W: bool> Guard<'lock, Value, Strategy, W> {
  142. /// # Safety
  143. /// Use of the lock after calling this function without relocking is undefined behavior.
  144. #[inline(always)]
  145. pub unsafe fn force_unlock(&mut self) {
  146. Strategy::do_temporary_unlock(&self.strategy_data, &mut self.context)
  147. }
  148. /// # Safety
  149. /// Calling this function more than once will cause deadlocks.
  150. #[inline(always)]
  151. pub unsafe fn force_relock(&mut self) {
  152. Strategy::do_relock(&self.strategy_data, &mut self.context)
  153. }
  154. }
  155. impl<'lock, Value: ?Sized, Strategy: LockStrategy, const WRITE: bool> Deref
  156. for Guard<'lock, Value, Strategy, WRITE>
  157. {
  158. type Target = Value;
  159. fn deref(&self) -> &Self::Target {
  160. unsafe { &*self.value.get() }
  161. }
  162. }
  163. impl<'lock, Value: ?Sized, Strategy: LockStrategy> DerefMut
  164. for Guard<'lock, Value, Strategy, true>
  165. {
  166. fn deref_mut(&mut self) -> &mut Self::Target {
  167. unsafe { &mut *self.value.get() }
  168. }
  169. }
  170. impl<'lock, Value: ?Sized, Strategy: LockStrategy, const WRITE: bool> AsRef<Value>
  171. for Guard<'lock, Value, Strategy, WRITE>
  172. {
  173. fn as_ref(&self) -> &Value {
  174. unsafe { &*self.value.get() }
  175. }
  176. }
  177. impl<'lock, Value: ?Sized, Strategy: LockStrategy> AsMut<Value>
  178. for Guard<'lock, Value, Strategy, true>
  179. {
  180. fn as_mut(&mut self) -> &mut Value {
  181. unsafe { &mut *self.value.get() }
  182. }
  183. }
  184. impl<'lock, Value: ?Sized, Strategy: LockStrategy, const WRITE: bool> Drop
  185. for Guard<'lock, Value, Strategy, WRITE>
  186. {
  187. fn drop(&mut self) {
  188. unsafe { Strategy::do_unlock(&self.strategy_data, &mut self.context) }
  189. }
  190. }