mutex.rs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. use core::{
  2. cell::UnsafeCell,
  3. ops::{Deref, DerefMut},
  4. };
  5. use alloc::collections::LinkedList;
  6. use crate::{
  7. arch::{asm::current::current_pcb, sched::sched},
  8. include::bindings::bindings::{
  9. pid_t, process_control_block, process_wakeup, PROC_INTERRUPTIBLE, PROC_RUNNING,
  10. },
  11. libs::spinlock::SpinLockGuard, syscall::SystemError,
  12. };
  13. use super::spinlock::SpinLock;
  14. #[derive(Debug)]
  15. struct MutexInner {
  16. /// 当前Mutex是否已经被上锁(上锁时,为true)
  17. is_locked: bool,
  18. /// 等待获得这个锁的进程的链表
  19. wait_list: LinkedList<&'static mut process_control_block>,
  20. }
  21. /// @brief Mutex互斥量结构体
  22. /// 请注意!由于Mutex属于休眠锁,因此,如果您的代码可能在中断上下文内执行,请勿采用Mutex!
  23. #[derive(Debug)]
  24. pub struct Mutex<T> {
  25. /// 该Mutex保护的数据
  26. data: UnsafeCell<T>,
  27. /// Mutex内部的信息
  28. inner: SpinLock<MutexInner>,
  29. }
  30. /// @brief Mutex的守卫
  31. #[derive(Debug)]
  32. pub struct MutexGuard<'a, T: 'a> {
  33. lock: &'a Mutex<T>,
  34. }
  35. unsafe impl<T> Sync for Mutex<T> where T: Send {}
  36. impl<T> Mutex<T> {
  37. /// @brief 初始化一个新的Mutex对象
  38. #[allow(dead_code)]
  39. pub const fn new(value: T) -> Self {
  40. return Self {
  41. data: UnsafeCell::new(value),
  42. inner: SpinLock::new(MutexInner {
  43. is_locked: false,
  44. wait_list: LinkedList::<&'static mut process_control_block>::new(),
  45. }),
  46. };
  47. }
  48. /// @brief 对Mutex加锁
  49. /// @return MutexGuard<T> 返回Mutex的守卫,您可以使用这个守卫来操作被保护的数据
  50. #[inline(always)]
  51. #[allow(dead_code)]
  52. pub fn lock(&self) -> MutexGuard<T> {
  53. loop {
  54. let mut inner: SpinLockGuard<MutexInner> = self.inner.lock();
  55. // 当前mutex已经上锁
  56. if inner.is_locked {
  57. // 检查当前进程是否处于等待队列中,如果不在,就加到等待队列内
  58. if self.check_pid_in_wait_list(&inner, current_pcb().pid) == false {
  59. inner.wait_list.push_back(current_pcb());
  60. }
  61. // 加到等待唤醒的队列,然后睡眠
  62. drop(inner);
  63. self.__sleep();
  64. } else {
  65. // 加锁成功
  66. inner.is_locked = true;
  67. drop(inner);
  68. break;
  69. }
  70. }
  71. // 加锁成功,返回一个守卫
  72. return MutexGuard { lock: self };
  73. }
  74. /// @brief 尝试对Mutex加锁。如果加锁失败,不会将当前进程加入等待队列。
  75. /// @return Ok 加锁成功,返回Mutex的守卫
  76. /// @return Err 如果Mutex当前已经上锁,则返回Err.
  77. #[inline(always)]
  78. #[allow(dead_code)]
  79. pub fn try_lock(&self) -> Result<MutexGuard<T>, SystemError> {
  80. let mut inner = self.inner.lock();
  81. // 如果当前mutex已经上锁,则失败
  82. if inner.is_locked {
  83. return Err(SystemError::EBUSY);
  84. } else {
  85. // 加锁成功
  86. inner.is_locked = true;
  87. return Ok(MutexGuard { lock: self });
  88. }
  89. }
  90. /// @brief Mutex内部的睡眠函数
  91. fn __sleep(&self) {
  92. current_pcb().state &= !(PROC_RUNNING as u64);
  93. current_pcb().state |= PROC_INTERRUPTIBLE as u64;
  94. sched();
  95. }
  96. /// @brief 放锁。
  97. ///
  98. /// 本函数只能是私有的,且只能被守卫的drop方法调用,否则将无法保证并发安全。
  99. fn unlock(&self) {
  100. let mut inner: SpinLockGuard<MutexInner> = self.inner.lock();
  101. // 当前mutex一定是已经加锁的状态
  102. assert!(inner.is_locked);
  103. // 标记mutex已经解锁
  104. inner.is_locked = false;
  105. if inner.wait_list.is_empty() {
  106. return;
  107. }
  108. // wait_list不为空,则获取下一个要被唤醒的进程的pcb
  109. let to_wakeup: &mut process_control_block = inner.wait_list.pop_front().unwrap();
  110. drop(inner);
  111. unsafe {
  112. process_wakeup(to_wakeup);
  113. }
  114. }
  115. /// @brief 检查进程是否在该mutex的等待队列内
  116. #[inline]
  117. fn check_pid_in_wait_list(&self, inner: &MutexInner, pid: pid_t) -> 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. }