1151251b5Slogin #![allow(dead_code)] 2*1496ba7bSLoGin use alloc::{collections::LinkedList, sync::Arc, vec::Vec}; 3c8025a88Slogin 4151251b5Slogin use crate::{ 5*1496ba7bSLoGin arch::{sched::sched, CurrentIrqArch}, 6f678331aShanjiezhou exception::InterruptArch, 7*1496ba7bSLoGin kerror, 8*1496ba7bSLoGin 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 /// 等待队列的链表 19*1496ba7bSLoGin 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) { 31*1496ba7bSLoGin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock_irqsave(); 32*1496ba7bSLoGin ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 33*1496ba7bSLoGin panic!("sleep error: {:?}", e); 34*1496ba7bSLoGin }); 35*1496ba7bSLoGin 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(); 46*1496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 47*1496ba7bSLoGin ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 48*1496ba7bSLoGin panic!("sleep error: {:?}", e); 49*1496ba7bSLoGin }); 50*1496ba7bSLoGin drop(irq_guard); 51*1496ba7bSLoGin 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(); 75*1496ba7bSLoGin ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 76*1496ba7bSLoGin panic!("sleep error: {:?}", e); 77*1496ba7bSLoGin }); 78*1496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 79*1496ba7bSLoGin drop(guard); 80*1496ba7bSLoGin } 81*1496ba7bSLoGin 82*1496ba7bSLoGin pub unsafe fn sleep_without_schedule_uninterruptible(&self) { 83*1496ba7bSLoGin // 安全检查:确保当前处于中断禁止状态 84*1496ba7bSLoGin assert!(CurrentIrqArch::is_irq_enabled() == false); 85*1496ba7bSLoGin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 86*1496ba7bSLoGin ProcessManager::mark_sleep(false).unwrap_or_else(|e| { 87*1496ba7bSLoGin panic!("sleep error: {:?}", e); 88*1496ba7bSLoGin }); 89*1496ba7bSLoGin 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(); 95*1496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 96*1496ba7bSLoGin ProcessManager::mark_sleep(false).unwrap_or_else(|e| { 97*1496ba7bSLoGin panic!("sleep error: {:?}", e); 98*1496ba7bSLoGin }); 99*1496ba7bSLoGin drop(irq_guard); 100*1496ba7bSLoGin 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(); 109*1496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 110*1496ba7bSLoGin ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 111*1496ba7bSLoGin panic!("sleep error: {:?}", e); 112*1496ba7bSLoGin }); 113*1496ba7bSLoGin drop(irq_guard); 114*1496ba7bSLoGin 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(); 124*1496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 125*1496ba7bSLoGin ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 126*1496ba7bSLoGin panic!("sleep error: {:?}", e); 127*1496ba7bSLoGin }); 128*1496ba7bSLoGin drop(irq_guard); 129*1496ba7bSLoGin 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(); 139*1496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 140*1496ba7bSLoGin ProcessManager::mark_sleep(false).unwrap_or_else(|e| { 141*1496ba7bSLoGin panic!("sleep error: {:?}", e); 142*1496ba7bSLoGin }); 143*1496ba7bSLoGin drop(irq_guard); 144*1496ba7bSLoGin 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(); 154*1496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 155*1496ba7bSLoGin ProcessManager::mark_sleep(false).unwrap_or_else(|e| { 156*1496ba7bSLoGin panic!("sleep error: {:?}", e); 157*1496ba7bSLoGin }); 158*1496ba7bSLoGin drop(irq_guard); 159*1496ba7bSLoGin 160*1496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 161*1496ba7bSLoGin 162151251b5Slogin drop(to_unlock); 163151251b5Slogin drop(guard); 164151251b5Slogin sched(); 165151251b5Slogin } 166151251b5Slogin 167151251b5Slogin /// @brief 唤醒在队列中等待的第一个进程。 168151251b5Slogin /// 如果这个进程的state与给定的state进行and操作之后,结果不为0,则唤醒它。 169151251b5Slogin /// 170*1496ba7bSLoGin /// @param state 用于判断的state,如果队列第一个进程与这个state相同,或者为None(表示不进行这个判断),则唤醒这个进程。 171151251b5Slogin /// 172151251b5Slogin /// @return true 成功唤醒进程 173151251b5Slogin /// @return false 没有唤醒进程 174*1496ba7bSLoGin 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,则唤醒 181*1496ba7bSLoGin if let Some(state) = state { 182*1496ba7bSLoGin if guard.wait_list.front().unwrap().sched_info().state() != state { 183151251b5Slogin return false; 184151251b5Slogin } 185151251b5Slogin } 186*1496ba7bSLoGin let to_wakeup = guard.wait_list.pop_front().unwrap(); 187*1496ba7bSLoGin let res = ProcessManager::wakeup(&to_wakeup).is_ok(); 188*1496ba7bSLoGin return res; 189*1496ba7bSLoGin } 190151251b5Slogin 191cde5492fSlogin /// @brief 唤醒在队列中,符合条件的所有进程。 192cde5492fSlogin /// 193*1496ba7bSLoGin /// @param state 用于判断的state,如果一个进程与这个state相同,或者为None(表示不进行这个判断),则唤醒这个进程。 194*1496ba7bSLoGin 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 201*1496ba7bSLoGin 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*1496ba7bSLoGin if let Some(state) = state { 205*1496ba7bSLoGin if to_wakeup.sched_info().state() == state { 206*1496ba7bSLoGin ProcessManager::wakeup(&to_wakeup).unwrap_or_else(|e| { 207*1496ba7bSLoGin kerror!("wakeup pid: {:?} error: {:?}", to_wakeup.pid(), e); 208*1496ba7bSLoGin }); 209*1496ba7bSLoGin continue; 210cde5492fSlogin } 211*1496ba7bSLoGin } 212cde5492fSlogin to_push_back.push(to_wakeup); 213cde5492fSlogin } 214cde5492fSlogin for to_wakeup in to_push_back { 215cde5492fSlogin guard.wait_list.push_back(to_wakeup); 216cde5492fSlogin } 217cde5492fSlogin } 218cde5492fSlogin 219151251b5Slogin /// @brief 获得当前等待队列的大小 220151251b5Slogin pub fn len(&self) -> usize { 221151251b5Slogin return self.0.lock().wait_list.len(); 222151251b5Slogin } 223151251b5Slogin } 224151251b5Slogin 225151251b5Slogin impl InnerWaitQueue { 226151251b5Slogin pub const INIT: InnerWaitQueue = InnerWaitQueue { 227151251b5Slogin wait_list: LinkedList::new(), 228151251b5Slogin }; 229151251b5Slogin } 230