wait_queue.rs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. // #![allow(dead_code)]
  2. use core::intrinsics::unlikely;
  3. use alloc::{collections::LinkedList, sync::Arc, vec::Vec};
  4. use crate::{
  5. arch::CurrentIrqArch,
  6. exception::InterruptArch,
  7. kerror,
  8. process::{ProcessControlBlock, ProcessManager, ProcessState},
  9. sched::{schedule, SchedMode},
  10. };
  11. use super::{
  12. mutex::MutexGuard,
  13. spinlock::{SpinLock, SpinLockGuard},
  14. };
  15. #[derive(Debug)]
  16. struct InnerWaitQueue {
  17. /// 等待队列的链表
  18. wait_list: LinkedList<Arc<ProcessControlBlock>>,
  19. }
  20. /// 被自旋锁保护的等待队列
  21. #[derive(Debug)]
  22. pub struct WaitQueue(SpinLock<InnerWaitQueue>);
  23. #[allow(dead_code)]
  24. impl WaitQueue {
  25. pub const fn default() -> Self {
  26. WaitQueue(SpinLock::new(InnerWaitQueue::INIT))
  27. }
  28. /// @brief 让当前进程在等待队列上进行等待,并且,允许被信号打断
  29. pub fn sleep(&self) {
  30. before_sleep_check(0);
  31. let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock_irqsave();
  32. ProcessManager::mark_sleep(true).unwrap_or_else(|e| {
  33. panic!("sleep error: {:?}", e);
  34. });
  35. guard.wait_list.push_back(ProcessManager::current_pcb());
  36. drop(guard);
  37. schedule(SchedMode::SM_NONE);
  38. }
  39. /// @brief 让当前进程在等待队列上进行等待,并且,在释放waitqueue的锁之前,执行f函数闭包
  40. pub fn sleep_with_func<F>(&self, f: F)
  41. where
  42. F: FnOnce(),
  43. {
  44. before_sleep_check(0);
  45. let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
  46. let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
  47. ProcessManager::mark_sleep(true).unwrap_or_else(|e| {
  48. panic!("sleep error: {:?}", e);
  49. });
  50. drop(irq_guard);
  51. guard.wait_list.push_back(ProcessManager::current_pcb());
  52. f();
  53. drop(guard);
  54. schedule(SchedMode::SM_NONE);
  55. }
  56. /// @brief 让当前进程在等待队列上进行等待. 但是,在释放waitqueue的锁之后,不会调用调度函数。
  57. /// 这样的设计,是为了让调用者可以在执行本函数之后,执行一些操作,然后再【手动调用调度函数】。
  58. ///
  59. /// 执行本函数前,需要确保处于【中断禁止】状态。
  60. ///
  61. /// 尽管sleep_with_func和sleep_without_schedule都可以实现这个功能,但是,sleep_with_func会在释放锁之前,执行f函数闭包。
  62. ///
  63. /// 考虑这样一个场景:
  64. /// 等待队列位于某个自旋锁保护的数据结构A中,我们希望在进程睡眠的同时,释放数据结构A的锁。
  65. /// 在这种情况下,如果使用sleep_with_func,所有权系统不会允许我们这么做。
  66. /// 因此,sleep_without_schedule的设计,正是为了解决这个问题。
  67. ///
  68. /// 由于sleep_without_schedule不会调用调度函数,因此,如果开发者忘记在执行本函数之后,手动调用调度函数,
  69. /// 由于时钟中断到来或者‘其他cpu kick了当前cpu’,可能会导致一些未定义的行为。
  70. pub unsafe fn sleep_without_schedule(&self) {
  71. before_sleep_check(1);
  72. // 安全检查:确保当前处于中断禁止状态
  73. assert!(!CurrentIrqArch::is_irq_enabled());
  74. let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
  75. ProcessManager::mark_sleep(true).unwrap_or_else(|e| {
  76. panic!("sleep error: {:?}", e);
  77. });
  78. guard.wait_list.push_back(ProcessManager::current_pcb());
  79. drop(guard);
  80. }
  81. pub unsafe fn sleep_without_schedule_uninterruptible(&self) {
  82. before_sleep_check(1);
  83. // 安全检查:确保当前处于中断禁止状态
  84. assert!(!CurrentIrqArch::is_irq_enabled());
  85. let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
  86. ProcessManager::mark_sleep(false).unwrap_or_else(|e| {
  87. panic!("sleep error: {:?}", e);
  88. });
  89. guard.wait_list.push_back(ProcessManager::current_pcb());
  90. drop(guard);
  91. }
  92. /// @brief 让当前进程在等待队列上进行等待,并且,不允许被信号打断
  93. pub fn sleep_uninterruptible(&self) {
  94. before_sleep_check(0);
  95. let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
  96. let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
  97. ProcessManager::mark_sleep(false).unwrap_or_else(|e| {
  98. panic!("sleep error: {:?}", e);
  99. });
  100. drop(irq_guard);
  101. guard.wait_list.push_back(ProcessManager::current_pcb());
  102. drop(guard);
  103. schedule(SchedMode::SM_NONE);
  104. }
  105. /// @brief 让当前进程在等待队列上进行等待,并且,允许被信号打断。
  106. /// 在当前进程的pcb加入队列后,解锁指定的自旋锁。
  107. pub fn sleep_unlock_spinlock<T>(&self, to_unlock: SpinLockGuard<T>) {
  108. before_sleep_check(1);
  109. let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
  110. let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
  111. ProcessManager::mark_sleep(true).unwrap_or_else(|e| {
  112. panic!("sleep error: {:?}", e);
  113. });
  114. drop(irq_guard);
  115. guard.wait_list.push_back(ProcessManager::current_pcb());
  116. drop(to_unlock);
  117. drop(guard);
  118. schedule(SchedMode::SM_NONE);
  119. }
  120. /// @brief 让当前进程在等待队列上进行等待,并且,允许被信号打断。
  121. /// 在当前进程的pcb加入队列后,解锁指定的Mutex。
  122. pub fn sleep_unlock_mutex<T>(&self, to_unlock: MutexGuard<T>) {
  123. before_sleep_check(1);
  124. let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
  125. let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
  126. ProcessManager::mark_sleep(true).unwrap_or_else(|e| {
  127. panic!("sleep error: {:?}", e);
  128. });
  129. drop(irq_guard);
  130. guard.wait_list.push_back(ProcessManager::current_pcb());
  131. drop(to_unlock);
  132. drop(guard);
  133. schedule(SchedMode::SM_NONE);
  134. }
  135. /// @brief 让当前进程在等待队列上进行等待,并且,不允许被信号打断。
  136. /// 在当前进程的pcb加入队列后,解锁指定的自旋锁。
  137. pub fn sleep_uninterruptible_unlock_spinlock<T>(&self, to_unlock: SpinLockGuard<T>) {
  138. before_sleep_check(1);
  139. let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
  140. let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
  141. ProcessManager::mark_sleep(false).unwrap_or_else(|e| {
  142. panic!("sleep error: {:?}", e);
  143. });
  144. drop(irq_guard);
  145. guard.wait_list.push_back(ProcessManager::current_pcb());
  146. drop(to_unlock);
  147. drop(guard);
  148. schedule(SchedMode::SM_NONE);
  149. }
  150. /// @brief 让当前进程在等待队列上进行等待,并且,不允许被信号打断。
  151. /// 在当前进程的pcb加入队列后,解锁指定的Mutex。
  152. pub fn sleep_uninterruptible_unlock_mutex<T>(&self, to_unlock: MutexGuard<T>) {
  153. before_sleep_check(1);
  154. let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
  155. let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
  156. ProcessManager::mark_sleep(false).unwrap_or_else(|e| {
  157. panic!("sleep error: {:?}", e);
  158. });
  159. drop(irq_guard);
  160. guard.wait_list.push_back(ProcessManager::current_pcb());
  161. drop(to_unlock);
  162. drop(guard);
  163. schedule(SchedMode::SM_NONE);
  164. }
  165. /// @brief 唤醒在队列中等待的第一个进程。
  166. /// 如果这个进程的state与给定的state进行and操作之后,结果不为0,则唤醒它。
  167. ///
  168. /// @param state 用于判断的state,如果队列第一个进程与这个state相同,或者为None(表示不进行这个判断),则唤醒这个进程。
  169. ///
  170. /// @return true 成功唤醒进程
  171. /// @return false 没有唤醒进程
  172. pub fn wakeup(&self, state: Option<ProcessState>) -> bool {
  173. let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock_irqsave();
  174. // 如果队列为空,则返回
  175. if guard.wait_list.is_empty() {
  176. return false;
  177. }
  178. // 如果队列头部的pcb的state与给定的state相与,结果不为0,则唤醒
  179. if let Some(state) = state {
  180. if guard
  181. .wait_list
  182. .front()
  183. .unwrap()
  184. .sched_info()
  185. .inner_lock_read_irqsave()
  186. .state()
  187. != state
  188. {
  189. return false;
  190. }
  191. }
  192. let to_wakeup = guard.wait_list.pop_front().unwrap();
  193. drop(guard);
  194. let res = ProcessManager::wakeup(&to_wakeup).is_ok();
  195. return res;
  196. }
  197. /// @brief 唤醒在队列中,符合条件的所有进程。
  198. ///
  199. /// @param state 用于判断的state,如果一个进程与这个state相同,或者为None(表示不进行这个判断),则唤醒这个进程。
  200. pub fn wakeup_all(&self, state: Option<ProcessState>) {
  201. let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock_irqsave();
  202. // 如果队列为空,则返回
  203. if guard.wait_list.is_empty() {
  204. return;
  205. }
  206. let mut to_push_back: Vec<Arc<ProcessControlBlock>> = Vec::new();
  207. // 如果队列头部的pcb的state与给定的state相与,结果不为0,则唤醒
  208. while let Some(to_wakeup) = guard.wait_list.pop_front() {
  209. let mut wake = false;
  210. if let Some(state) = state {
  211. if to_wakeup.sched_info().inner_lock_read_irqsave().state() == state {
  212. wake = true;
  213. }
  214. } else {
  215. wake = true;
  216. }
  217. if wake {
  218. ProcessManager::wakeup(&to_wakeup).unwrap_or_else(|e| {
  219. kerror!("wakeup pid: {:?} error: {:?}", to_wakeup.pid(), e);
  220. });
  221. continue;
  222. } else {
  223. to_push_back.push(to_wakeup);
  224. }
  225. }
  226. for to_wakeup in to_push_back {
  227. guard.wait_list.push_back(to_wakeup);
  228. }
  229. }
  230. /// @brief 获得当前等待队列的大小
  231. pub fn len(&self) -> usize {
  232. return self.0.lock().wait_list.len();
  233. }
  234. }
  235. impl InnerWaitQueue {
  236. pub const INIT: InnerWaitQueue = InnerWaitQueue {
  237. wait_list: LinkedList::new(),
  238. };
  239. }
  240. fn before_sleep_check(max_preempt: usize) {
  241. let pcb = ProcessManager::current_pcb();
  242. if unlikely(pcb.preempt_count() > max_preempt) {
  243. kwarn!(
  244. "Process {:?}: Try to sleep when preempt count is {}",
  245. pcb.pid().data(),
  246. pcb.preempt_count()
  247. );
  248. }
  249. }
  250. /// 事件等待队列
  251. #[derive(Debug)]
  252. pub struct EventWaitQueue {
  253. wait_list: SpinLock<Vec<(u64, Arc<ProcessControlBlock>)>>,
  254. }
  255. impl Default for EventWaitQueue {
  256. fn default() -> Self {
  257. Self::new()
  258. }
  259. }
  260. #[allow(dead_code)]
  261. impl EventWaitQueue {
  262. pub fn new() -> Self {
  263. Self {
  264. wait_list: SpinLock::new(Default::default()),
  265. }
  266. }
  267. /// ## 让当前进程在该队列上等待感兴趣的事件
  268. ///
  269. /// ### 参数
  270. /// - events: 进程感兴趣的事件,events最好是为位表示,一位表示一个事件
  271. ///
  272. /// 注意,使用前应该注意有可能其他地方定义了冲突的事件,可能会导致未定义行为
  273. pub fn sleep(&self, events: u64) {
  274. before_sleep_check(0);
  275. let mut guard = self.wait_list.lock_irqsave();
  276. ProcessManager::mark_sleep(true).unwrap_or_else(|e| {
  277. panic!("sleep error: {:?}", e);
  278. });
  279. guard.push((events, ProcessManager::current_pcb()));
  280. drop(guard);
  281. schedule(SchedMode::SM_NONE);
  282. }
  283. pub unsafe fn sleep_without_schedule(&self, events: u64) {
  284. before_sleep_check(1);
  285. let mut guard = self.wait_list.lock_irqsave();
  286. ProcessManager::mark_sleep(true).unwrap_or_else(|e| {
  287. panic!("sleep error: {:?}", e);
  288. });
  289. guard.push((events, ProcessManager::current_pcb()));
  290. drop(guard);
  291. }
  292. pub fn sleep_unlock_spinlock<T>(&self, events: u64, to_unlock: SpinLockGuard<T>) {
  293. before_sleep_check(1);
  294. let mut guard = self.wait_list.lock_irqsave();
  295. let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
  296. ProcessManager::mark_sleep(true).unwrap_or_else(|e| {
  297. panic!("sleep error: {:?}", e);
  298. });
  299. drop(irq_guard);
  300. guard.push((events, ProcessManager::current_pcb()));
  301. drop(to_unlock);
  302. drop(guard);
  303. schedule(SchedMode::SM_NONE);
  304. }
  305. /// ### 唤醒该队列上等待events的进程
  306. ///
  307. /// ### 参数
  308. /// - events: 发生的事件
  309. ///
  310. /// 需要注意的是,只要触发了events中的任意一件事件,进程都会被唤醒
  311. pub fn wakeup_any(&self, events: u64) -> usize {
  312. let mut ret = 0;
  313. let mut wq_guard = self.wait_list.lock_irqsave();
  314. wq_guard.retain(|(es, pcb)| {
  315. if *es & events > 0 {
  316. // 有感兴趣的事件
  317. if ProcessManager::wakeup(pcb).is_ok() {
  318. ret += 1;
  319. return false;
  320. } else {
  321. return true;
  322. }
  323. } else {
  324. return true;
  325. }
  326. });
  327. ret
  328. }
  329. /// ### 唤醒该队列上等待events的进程
  330. ///
  331. /// ### 参数
  332. /// - events: 发生的事件
  333. ///
  334. /// 需要注意的是,只有满足所有事件的进程才会被唤醒
  335. pub fn wakeup(&self, events: u64) -> usize {
  336. let mut ret = 0;
  337. let mut wq_guard = self.wait_list.lock_irqsave();
  338. wq_guard.retain(|(es, pcb)| {
  339. if *es == events {
  340. // 有感兴趣的事件
  341. if ProcessManager::wakeup(pcb).is_ok() {
  342. ret += 1;
  343. return false;
  344. } else {
  345. return true;
  346. }
  347. } else {
  348. return true;
  349. }
  350. });
  351. ret
  352. }
  353. pub fn wakeup_all(&self) {
  354. self.wakeup_any(u64::MAX);
  355. }
  356. }