spinlock.rs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. #![allow(dead_code)]
  2. use core::cell::UnsafeCell;
  3. use core::ops::{Deref, DerefMut};
  4. use core::ptr::read_volatile;
  5. use core::sync::atomic::{AtomicBool, Ordering};
  6. use crate::arch::asm::irqflags::{local_irq_restore, local_irq_save};
  7. use crate::arch::interrupt::{cli, sti};
  8. use crate::include::bindings::bindings::{spin_lock, spin_unlock, spinlock_t};
  9. use crate::process::preempt::{preempt_disable, preempt_enable};
  10. /// @brief 保存中断状态到flags中,关闭中断,并对自旋锁加锁
  11. #[inline]
  12. pub fn spin_lock_irqsave(lock: *mut spinlock_t, flags: &mut u64) {
  13. local_irq_save(flags);
  14. unsafe {
  15. spin_lock(lock);
  16. }
  17. }
  18. /// @brief 恢复rflags以及中断状态并解锁自旋锁
  19. #[inline]
  20. pub fn spin_unlock_irqrestore(lock: *mut spinlock_t, flags: &u64) {
  21. unsafe {
  22. spin_unlock(lock);
  23. }
  24. // kdebug!("123");
  25. local_irq_restore(flags);
  26. }
  27. /// 判断一个自旋锁是否已经被加锁
  28. #[inline]
  29. pub fn spin_is_locked(lock: &spinlock_t) -> bool {
  30. let val = unsafe { read_volatile(&lock.lock as *const i8) };
  31. return if val == 0 { true } else { false };
  32. }
  33. impl Default for spinlock_t {
  34. fn default() -> Self {
  35. Self { lock: 1 }
  36. }
  37. }
  38. /// @brief 关闭中断并加锁
  39. pub fn spin_lock_irq(lock: *mut spinlock_t) {
  40. cli();
  41. unsafe {
  42. spin_lock(lock);
  43. }
  44. }
  45. /// @brief 解锁并开中断
  46. pub fn spin_unlock_irq(lock: *mut spinlock_t) {
  47. unsafe {
  48. spin_unlock(lock);
  49. }
  50. sti();
  51. }
  52. /// 原始的Spinlock(自旋锁)
  53. /// 请注意,这个自旋锁和C的不兼容。
  54. ///
  55. /// @param self.0 这个AtomicBool的值为false时,表示没有被加锁。当它为true时,表示自旋锁已经被上锁。
  56. #[derive(Debug)]
  57. pub struct RawSpinlock(AtomicBool);
  58. impl RawSpinlock {
  59. /// @brief 初始化自旋锁
  60. pub const INIT: RawSpinlock = RawSpinlock(AtomicBool::new(false));
  61. /// @brief 加锁
  62. pub fn lock(&self) {
  63. while !self.try_lock() {}
  64. }
  65. /// @brief 关中断并加锁
  66. pub fn lock_irq(&self) {
  67. cli();
  68. self.lock();
  69. }
  70. /// @brief 尝试加锁
  71. /// @return 加锁成功->true
  72. /// 加锁失败->false
  73. pub fn try_lock(&self) -> bool {
  74. // 先增加自旋锁持有计数
  75. preempt_disable();
  76. let res = self
  77. .0
  78. .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed)
  79. .is_ok();
  80. // 如果加锁失败恢复自旋锁持有计数
  81. if res == false {
  82. preempt_enable();
  83. }
  84. return res;
  85. }
  86. /// @brief 解锁
  87. pub fn unlock(&self) {
  88. // 减少自旋锁持有计数
  89. preempt_enable();
  90. self.0.store(false, Ordering::Release);
  91. }
  92. /// @brief 放锁并开中断
  93. pub fn unlock_irq(&self) {
  94. self.unlock();
  95. sti();
  96. }
  97. /// @brief 判断自旋锁是否被上锁
  98. ///
  99. /// @return true 自旋锁被上锁
  100. /// @return false 自旋锁处于解锁状态
  101. pub fn is_locked(&self) -> bool {
  102. return self.0.load(Ordering::Relaxed).into();
  103. }
  104. /// @brief 强制设置自旋锁的状态
  105. /// 请注意,这样操作可能会带来未知的风险。因此它是unsafe的。(尽管从Rust语言本身来说,它是safe的)
  106. pub unsafe fn set_value(&mut self, value: bool) {
  107. self.0.store(value, Ordering::SeqCst);
  108. }
  109. /// @brief 保存中断状态到flags中,关闭中断,并对自旋锁加锁
  110. pub fn lock_irqsave(&self, flags: &mut u64) {
  111. local_irq_save(flags);
  112. self.lock();
  113. }
  114. /// @brief 恢复rflags以及中断状态并解锁自旋锁
  115. pub fn unlock_irqrestore(&self, flags: &u64){
  116. self.unlock();
  117. local_irq_restore(flags);
  118. }
  119. }
  120. /// 实现了守卫的SpinLock, 能够支持内部可变性
  121. ///
  122. #[derive(Debug)]
  123. pub struct SpinLock<T> {
  124. lock: RawSpinlock,
  125. /// 自旋锁保护的数据
  126. data: UnsafeCell<T>,
  127. }
  128. /// SpinLock的守卫
  129. /// 该守卫没有构造器,并且其信息均为私有的。我们只能通过SpinLock的lock()方法获得一个守卫。
  130. /// 因此我们可以认为,只要能够获得一个守卫,那么数据就在自旋锁的保护之下。
  131. #[derive(Debug)]
  132. pub struct SpinLockGuard<'a, T: 'a> {
  133. lock: &'a SpinLock<T>,
  134. }
  135. /// 向编译器保证,SpinLock在线程之间是安全的.
  136. /// 其中要求类型T实现了Send这个Trait
  137. unsafe impl<T> Sync for SpinLock<T> where T: Send {}
  138. impl<T> SpinLock<T> {
  139. pub const fn new(value: T) -> Self {
  140. return Self {
  141. lock: RawSpinlock::INIT,
  142. data: UnsafeCell::new(value),
  143. };
  144. }
  145. #[inline(always)]
  146. pub fn lock(&self) -> SpinLockGuard<T> {
  147. self.lock.lock();
  148. // 加锁成功,返回一个守卫
  149. return SpinLockGuard { lock: self };
  150. }
  151. }
  152. /// 实现Deref trait,支持通过获取SpinLockGuard来获取临界区数据的不可变引用
  153. impl<T> Deref for SpinLockGuard<'_, T> {
  154. type Target = T;
  155. fn deref(&self) -> &Self::Target {
  156. return unsafe { &*self.lock.data.get() };
  157. }
  158. }
  159. /// 实现DerefMut trait,支持通过获取SpinLockGuard来获取临界区数据的可变引用
  160. impl<T> DerefMut for SpinLockGuard<'_, T> {
  161. fn deref_mut(&mut self) -> &mut Self::Target {
  162. return unsafe { &mut *self.lock.data.get() };
  163. }
  164. }
  165. /// @brief 为SpinLockGuard实现Drop方法,那么,一旦守卫的生命周期结束,就会自动释放自旋锁,避免了忘记放锁的情况
  166. impl<T> Drop for SpinLockGuard<'_, T> {
  167. fn drop(&mut self) {
  168. self.lock.lock.unlock();
  169. }
  170. }