mutex.rs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. use core::{
  2. cell::UnsafeCell,
  3. ops::{Deref, DerefMut},
  4. };
  5. use alloc::{collections::LinkedList, sync::Arc};
  6. use system_error::SystemError;
  7. use crate::{
  8. arch::CurrentIrqArch,
  9. exception::InterruptArch,
  10. libs::spinlock::SpinLockGuard,
  11. process::{Pid, ProcessControlBlock, ProcessManager},
  12. sched::{schedule, SchedMode},
  13. };
  14. use super::spinlock::SpinLock;
  15. #[derive(Debug)]
  16. struct MutexInner {
  17. /// 当前Mutex是否已经被上锁(上锁时,为true)
  18. is_locked: bool,
  19. /// 等待获得这个锁的进程的链表
  20. wait_list: LinkedList<Arc<ProcessControlBlock>>,
  21. }
  22. /// @brief Mutex互斥量结构体
  23. /// 请注意!由于Mutex属于休眠锁,因此,如果您的代码可能在中断上下文内执行,请勿采用Mutex!
  24. #[derive(Debug)]
  25. pub struct Mutex<T> {
  26. /// 该Mutex保护的数据
  27. data: UnsafeCell<T>,
  28. /// Mutex内部的信息
  29. inner: SpinLock<MutexInner>,
  30. }
  31. /// @brief Mutex的守卫
  32. #[derive(Debug)]
  33. pub struct MutexGuard<'a, T: 'a> {
  34. lock: &'a Mutex<T>,
  35. }
  36. unsafe impl<T> Sync for Mutex<T> where T: Send {}
  37. impl<T> Mutex<T> {
  38. /// @brief 初始化一个新的Mutex对象
  39. #[allow(dead_code)]
  40. pub const fn new(value: T) -> Self {
  41. return Self {
  42. data: UnsafeCell::new(value),
  43. inner: SpinLock::new(MutexInner {
  44. is_locked: false,
  45. wait_list: LinkedList::new(),
  46. }),
  47. };
  48. }
  49. /// @brief 对Mutex加锁
  50. /// @return MutexGuard<T> 返回Mutex的守卫,您可以使用这个守卫来操作被保护的数据
  51. #[inline(always)]
  52. #[allow(dead_code)]
  53. pub fn lock(&self) -> MutexGuard<T> {
  54. loop {
  55. let mut inner: SpinLockGuard<MutexInner> = self.inner.lock();
  56. // 当前mutex已经上锁
  57. if inner.is_locked {
  58. // 检查当前进程是否处于等待队列中,如果不在,就加到等待队列内
  59. if !self.check_pid_in_wait_list(&inner, ProcessManager::current_pcb().pid()) {
  60. inner.wait_list.push_back(ProcessManager::current_pcb());
  61. }
  62. // 加到等待唤醒的队列,然后睡眠
  63. drop(inner);
  64. self.__sleep();
  65. } else {
  66. // 加锁成功
  67. inner.is_locked = true;
  68. drop(inner);
  69. break;
  70. }
  71. }
  72. // 加锁成功,返回一个守卫
  73. return MutexGuard { lock: self };
  74. }
  75. /// @brief 尝试对Mutex加锁。如果加锁失败,不会将当前进程加入等待队列。
  76. /// @return Ok 加锁成功,返回Mutex的守卫
  77. /// @return Err 如果Mutex当前已经上锁,则返回Err.
  78. #[inline(always)]
  79. #[allow(dead_code)]
  80. pub fn try_lock(&self) -> Result<MutexGuard<T>, SystemError> {
  81. let mut inner = self.inner.lock();
  82. // 如果当前mutex已经上锁,则失败
  83. if inner.is_locked {
  84. return Err(SystemError::EBUSY);
  85. } else {
  86. // 加锁成功
  87. inner.is_locked = true;
  88. return Ok(MutexGuard { lock: self });
  89. }
  90. }
  91. /// @brief Mutex内部的睡眠函数
  92. fn __sleep(&self) {
  93. let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
  94. ProcessManager::mark_sleep(true).ok();
  95. drop(irq_guard);
  96. schedule(SchedMode::SM_NONE);
  97. }
  98. /// @brief 放锁。
  99. ///
  100. /// 本函数只能是私有的,且只能被守卫的drop方法调用,否则将无法保证并发安全。
  101. fn unlock(&self) {
  102. let mut inner: SpinLockGuard<MutexInner> = self.inner.lock();
  103. // 当前mutex一定是已经加锁的状态
  104. assert!(inner.is_locked);
  105. // 标记mutex已经解锁
  106. inner.is_locked = false;
  107. if inner.wait_list.is_empty() {
  108. return;
  109. }
  110. // wait_list不为空,则获取下一个要被唤醒的进程的pcb
  111. let to_wakeup: Arc<ProcessControlBlock> = inner.wait_list.pop_front().unwrap();
  112. drop(inner);
  113. ProcessManager::wakeup(&to_wakeup).ok();
  114. }
  115. /// @brief 检查进程是否在该mutex的等待队列内
  116. #[inline]
  117. fn check_pid_in_wait_list(&self, inner: &MutexInner, pid: Pid) -> bool {
  118. for p in inner.wait_list.iter() {
  119. if p.pid() == pid {
  120. // 在等待队列内
  121. return true;
  122. }
  123. }
  124. // 不在等待队列内
  125. return false;
  126. }
  127. }
  128. /// 实现Deref trait,支持通过获取MutexGuard来获取临界区数据的不可变引用
  129. impl<T> Deref for MutexGuard<'_, T> {
  130. type Target = T;
  131. fn deref(&self) -> &Self::Target {
  132. return unsafe { &*self.lock.data.get() };
  133. }
  134. }
  135. /// 实现DerefMut trait,支持通过获取MutexGuard来获取临界区数据的可变引用
  136. impl<T> DerefMut for MutexGuard<'_, T> {
  137. fn deref_mut(&mut self) -> &mut Self::Target {
  138. return unsafe { &mut *self.lock.data.get() };
  139. }
  140. }
  141. /// @brief 为MutexGuard实现Drop方法,那么,一旦守卫的生命周期结束,就会自动释放自旋锁,避免了忘记放锁的情况
  142. impl<T> Drop for MutexGuard<'_, T> {
  143. fn drop(&mut self) {
  144. self.lock.unlock();
  145. }
  146. }