1151251b5Slogin #![allow(dead_code)] 21496ba7bSLoGin use alloc::{collections::LinkedList, sync::Arc, vec::Vec}; 3c8025a88Slogin 4151251b5Slogin use crate::{ 51496ba7bSLoGin arch::{sched::sched, CurrentIrqArch}, 6f678331aShanjiezhou exception::InterruptArch, 71496ba7bSLoGin kerror, 81496ba7bSLoGin process::{ProcessControlBlock, ProcessManager, ProcessState}, 9151251b5Slogin }; 10151251b5Slogin 11151251b5Slogin use super::{ 12151251b5Slogin mutex::MutexGuard, 13151251b5Slogin spinlock::{SpinLock, SpinLockGuard}, 14151251b5Slogin }; 15c8025a88Slogin 16151251b5Slogin #[derive(Debug)] 17151251b5Slogin struct InnerWaitQueue { 18151251b5Slogin /// 等待队列的链表 191496ba7bSLoGin wait_list: LinkedList<Arc<ProcessControlBlock>>, 20151251b5Slogin } 21151251b5Slogin 22151251b5Slogin /// 被自旋锁保护的等待队列 23151251b5Slogin #[derive(Debug)] 24151251b5Slogin pub struct WaitQueue(SpinLock<InnerWaitQueue>); 25151251b5Slogin 26151251b5Slogin impl WaitQueue { 27151251b5Slogin pub const INIT: WaitQueue = WaitQueue(SpinLock::new(InnerWaitQueue::INIT)); 28151251b5Slogin 29151251b5Slogin /// @brief 让当前进程在等待队列上进行等待,并且,允许被信号打断 30151251b5Slogin pub fn sleep(&self) { 311496ba7bSLoGin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock_irqsave(); 321496ba7bSLoGin ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 331496ba7bSLoGin panic!("sleep error: {:?}", e); 341496ba7bSLoGin }); 351496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 36151251b5Slogin drop(guard); 37151251b5Slogin sched(); 38151251b5Slogin } 39151251b5Slogin 40f678331aShanjiezhou /// @brief 让当前进程在等待队列上进行等待,并且,在释放waitqueue的锁之前,执行f函数闭包 41f678331aShanjiezhou pub fn sleep_with_func<F>(&self, f: F) 42f678331aShanjiezhou where 43f678331aShanjiezhou F: FnOnce(), 44f678331aShanjiezhou { 45f678331aShanjiezhou let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 461496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 471496ba7bSLoGin ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 481496ba7bSLoGin panic!("sleep error: {:?}", e); 491496ba7bSLoGin }); 501496ba7bSLoGin drop(irq_guard); 511496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 52f678331aShanjiezhou f(); 53f678331aShanjiezhou drop(guard); 54f678331aShanjiezhou sched(); 55f678331aShanjiezhou } 56f678331aShanjiezhou 57f678331aShanjiezhou /// @brief 让当前进程在等待队列上进行等待. 但是,在释放waitqueue的锁之后,不会调用调度函数。 58f678331aShanjiezhou /// 这样的设计,是为了让调用者可以在执行本函数之后,执行一些操作,然后再【手动调用调度函数】。 59f678331aShanjiezhou /// 60f678331aShanjiezhou /// 执行本函数前,需要确保处于【中断禁止】状态。 61f678331aShanjiezhou /// 62f678331aShanjiezhou /// 尽管sleep_with_func和sleep_without_schedule都可以实现这个功能,但是,sleep_with_func会在释放锁之前,执行f函数闭包。 63f678331aShanjiezhou /// 64f678331aShanjiezhou /// 考虑这样一个场景: 65f678331aShanjiezhou /// 等待队列位于某个自旋锁保护的数据结构A中,我们希望在进程睡眠的同时,释放数据结构A的锁。 66f678331aShanjiezhou /// 在这种情况下,如果使用sleep_with_func,所有权系统不会允许我们这么做。 67f678331aShanjiezhou /// 因此,sleep_without_schedule的设计,正是为了解决这个问题。 68f678331aShanjiezhou /// 69f678331aShanjiezhou /// 由于sleep_without_schedule不会调用调度函数,因此,如果开发者忘记在执行本函数之后,手动调用调度函数, 70f678331aShanjiezhou /// 由于时钟中断到来或者‘其他cpu kick了当前cpu’,可能会导致一些未定义的行为。 71f678331aShanjiezhou pub unsafe fn sleep_without_schedule(&self) { 72f678331aShanjiezhou // 安全检查:确保当前处于中断禁止状态 73f678331aShanjiezhou assert!(CurrentIrqArch::is_irq_enabled() == false); 74f678331aShanjiezhou let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 751496ba7bSLoGin ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 761496ba7bSLoGin panic!("sleep error: {:?}", e); 771496ba7bSLoGin }); 781496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 791496ba7bSLoGin drop(guard); 801496ba7bSLoGin } 811496ba7bSLoGin 821496ba7bSLoGin pub unsafe fn sleep_without_schedule_uninterruptible(&self) { 831496ba7bSLoGin // 安全检查:确保当前处于中断禁止状态 841496ba7bSLoGin assert!(CurrentIrqArch::is_irq_enabled() == false); 851496ba7bSLoGin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 861496ba7bSLoGin ProcessManager::mark_sleep(false).unwrap_or_else(|e| { 871496ba7bSLoGin panic!("sleep error: {:?}", e); 881496ba7bSLoGin }); 891496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 90f678331aShanjiezhou drop(guard); 91f678331aShanjiezhou } 92151251b5Slogin /// @brief 让当前进程在等待队列上进行等待,并且,不允许被信号打断 93151251b5Slogin pub fn sleep_uninterruptible(&self) { 94151251b5Slogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 951496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 961496ba7bSLoGin ProcessManager::mark_sleep(false).unwrap_or_else(|e| { 971496ba7bSLoGin panic!("sleep error: {:?}", e); 981496ba7bSLoGin }); 991496ba7bSLoGin drop(irq_guard); 1001496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 101151251b5Slogin drop(guard); 102151251b5Slogin sched(); 103151251b5Slogin } 104151251b5Slogin 105151251b5Slogin /// @brief 让当前进程在等待队列上进行等待,并且,允许被信号打断。 106151251b5Slogin /// 在当前进程的pcb加入队列后,解锁指定的自旋锁。 107151251b5Slogin pub fn sleep_unlock_spinlock<T>(&self, to_unlock: SpinLockGuard<T>) { 108151251b5Slogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 1091496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 1101496ba7bSLoGin ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 1111496ba7bSLoGin panic!("sleep error: {:?}", e); 1121496ba7bSLoGin }); 1131496ba7bSLoGin drop(irq_guard); 1141496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 115151251b5Slogin drop(to_unlock); 116151251b5Slogin drop(guard); 117151251b5Slogin sched(); 118151251b5Slogin } 119151251b5Slogin 120151251b5Slogin /// @brief 让当前进程在等待队列上进行等待,并且,允许被信号打断。 121151251b5Slogin /// 在当前进程的pcb加入队列后,解锁指定的Mutex。 122151251b5Slogin pub fn sleep_unlock_mutex<T>(&self, to_unlock: MutexGuard<T>) { 123151251b5Slogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 1241496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 1251496ba7bSLoGin ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 1261496ba7bSLoGin panic!("sleep error: {:?}", e); 1271496ba7bSLoGin }); 1281496ba7bSLoGin drop(irq_guard); 1291496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 130151251b5Slogin drop(to_unlock); 131151251b5Slogin drop(guard); 132151251b5Slogin sched(); 133151251b5Slogin } 134151251b5Slogin 135151251b5Slogin /// @brief 让当前进程在等待队列上进行等待,并且,不允许被信号打断。 136151251b5Slogin /// 在当前进程的pcb加入队列后,解锁指定的自旋锁。 137151251b5Slogin pub fn sleep_uninterruptible_unlock_spinlock<T>(&self, to_unlock: SpinLockGuard<T>) { 138151251b5Slogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 1391496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 1401496ba7bSLoGin ProcessManager::mark_sleep(false).unwrap_or_else(|e| { 1411496ba7bSLoGin panic!("sleep error: {:?}", e); 1421496ba7bSLoGin }); 1431496ba7bSLoGin drop(irq_guard); 1441496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 145151251b5Slogin drop(to_unlock); 146151251b5Slogin drop(guard); 147151251b5Slogin sched(); 148151251b5Slogin } 149151251b5Slogin 150151251b5Slogin /// @brief 让当前进程在等待队列上进行等待,并且,不允许被信号打断。 151151251b5Slogin /// 在当前进程的pcb加入队列后,解锁指定的Mutex。 152151251b5Slogin pub fn sleep_uninterruptible_unlock_mutex<T>(&self, to_unlock: MutexGuard<T>) { 153151251b5Slogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 1541496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 1551496ba7bSLoGin ProcessManager::mark_sleep(false).unwrap_or_else(|e| { 1561496ba7bSLoGin panic!("sleep error: {:?}", e); 1571496ba7bSLoGin }); 1581496ba7bSLoGin drop(irq_guard); 1591496ba7bSLoGin 1601496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 1611496ba7bSLoGin 162151251b5Slogin drop(to_unlock); 163151251b5Slogin drop(guard); 164151251b5Slogin sched(); 165151251b5Slogin } 166151251b5Slogin 167151251b5Slogin /// @brief 唤醒在队列中等待的第一个进程。 168151251b5Slogin /// 如果这个进程的state与给定的state进行and操作之后,结果不为0,则唤醒它。 169151251b5Slogin /// 1701496ba7bSLoGin /// @param state 用于判断的state,如果队列第一个进程与这个state相同,或者为None(表示不进行这个判断),则唤醒这个进程。 171151251b5Slogin /// 172151251b5Slogin /// @return true 成功唤醒进程 173151251b5Slogin /// @return false 没有唤醒进程 1741496ba7bSLoGin pub fn wakeup(&self, state: Option<ProcessState>) -> bool { 175151251b5Slogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 176151251b5Slogin // 如果队列为空,则返回 177151251b5Slogin if guard.wait_list.is_empty() { 178151251b5Slogin return false; 179151251b5Slogin } 180151251b5Slogin // 如果队列头部的pcb的state与给定的state相与,结果不为0,则唤醒 1811496ba7bSLoGin if let Some(state) = state { 1821496ba7bSLoGin if guard.wait_list.front().unwrap().sched_info().state() != state { 183151251b5Slogin return false; 184151251b5Slogin } 185151251b5Slogin } 1861496ba7bSLoGin let to_wakeup = guard.wait_list.pop_front().unwrap(); 1871496ba7bSLoGin let res = ProcessManager::wakeup(&to_wakeup).is_ok(); 1881496ba7bSLoGin return res; 1891496ba7bSLoGin } 190151251b5Slogin 191cde5492fSlogin /// @brief 唤醒在队列中,符合条件的所有进程。 192cde5492fSlogin /// 1931496ba7bSLoGin /// @param state 用于判断的state,如果一个进程与这个state相同,或者为None(表示不进行这个判断),则唤醒这个进程。 1941496ba7bSLoGin pub fn wakeup_all(&self, state: Option<ProcessState>) { 195cde5492fSlogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock_irqsave(); 196cde5492fSlogin // 如果队列为空,则返回 197cde5492fSlogin if guard.wait_list.is_empty() { 198cde5492fSlogin return; 199cde5492fSlogin } 200cde5492fSlogin 2011496ba7bSLoGin let mut to_push_back: Vec<Arc<ProcessControlBlock>> = Vec::new(); 202cde5492fSlogin // 如果队列头部的pcb的state与给定的state相与,结果不为0,则唤醒 203cde5492fSlogin while let Some(to_wakeup) = guard.wait_list.pop_front() { 204*a03c4f9dSLoGin let mut wake = false; 2051496ba7bSLoGin if let Some(state) = state { 2061496ba7bSLoGin if to_wakeup.sched_info().state() == state { 207*a03c4f9dSLoGin wake = true; 208*a03c4f9dSLoGin } 209*a03c4f9dSLoGin } else { 210*a03c4f9dSLoGin wake = true; 211*a03c4f9dSLoGin } 212*a03c4f9dSLoGin 213*a03c4f9dSLoGin if wake { 2141496ba7bSLoGin ProcessManager::wakeup(&to_wakeup).unwrap_or_else(|e| { 2151496ba7bSLoGin kerror!("wakeup pid: {:?} error: {:?}", to_wakeup.pid(), e); 2161496ba7bSLoGin }); 2171496ba7bSLoGin continue; 218*a03c4f9dSLoGin } else { 219cde5492fSlogin to_push_back.push(to_wakeup); 220cde5492fSlogin } 221*a03c4f9dSLoGin } 222*a03c4f9dSLoGin 223cde5492fSlogin for to_wakeup in to_push_back { 224cde5492fSlogin guard.wait_list.push_back(to_wakeup); 225cde5492fSlogin } 226cde5492fSlogin } 227cde5492fSlogin 228151251b5Slogin /// @brief 获得当前等待队列的大小 229151251b5Slogin pub fn len(&self) -> usize { 230151251b5Slogin return self.0.lock().wait_list.len(); 231151251b5Slogin } 232151251b5Slogin } 233151251b5Slogin 234151251b5Slogin impl InnerWaitQueue { 235151251b5Slogin pub const INIT: InnerWaitQueue = InnerWaitQueue { 236151251b5Slogin wait_list: LinkedList::new(), 237151251b5Slogin }; 238151251b5Slogin } 239