1e2841179SLoGin // #![allow(dead_code)] 22f6f547aSGnoCiYeH use core::intrinsics::unlikely; 32f6f547aSGnoCiYeH 41496ba7bSLoGin use alloc::{collections::LinkedList, sync::Arc, vec::Vec}; 5c8025a88Slogin 6151251b5Slogin use crate::{ 71496ba7bSLoGin arch::{sched::sched, CurrentIrqArch}, 8f678331aShanjiezhou exception::InterruptArch, 91496ba7bSLoGin kerror, 101496ba7bSLoGin process::{ProcessControlBlock, ProcessManager, ProcessState}, 11151251b5Slogin }; 12151251b5Slogin 13151251b5Slogin use super::{ 14151251b5Slogin mutex::MutexGuard, 15151251b5Slogin spinlock::{SpinLock, SpinLockGuard}, 16151251b5Slogin }; 17c8025a88Slogin 18151251b5Slogin #[derive(Debug)] 19151251b5Slogin struct InnerWaitQueue { 20151251b5Slogin /// 等待队列的链表 211496ba7bSLoGin wait_list: LinkedList<Arc<ProcessControlBlock>>, 22151251b5Slogin } 23151251b5Slogin 24151251b5Slogin /// 被自旋锁保护的等待队列 25151251b5Slogin #[derive(Debug)] 26151251b5Slogin pub struct WaitQueue(SpinLock<InnerWaitQueue>); 27151251b5Slogin 28e2841179SLoGin #[allow(dead_code)] 29151251b5Slogin impl WaitQueue { 30*b5b571e0SLoGin pub const fn default() -> Self { 31*b5b571e0SLoGin WaitQueue(SpinLock::new(InnerWaitQueue::INIT)) 32*b5b571e0SLoGin } 33151251b5Slogin 34151251b5Slogin /// @brief 让当前进程在等待队列上进行等待,并且,允许被信号打断 35151251b5Slogin pub fn sleep(&self) { 3640609970SGnoCiYeH before_sleep_check(0); 371496ba7bSLoGin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock_irqsave(); 381496ba7bSLoGin ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 391496ba7bSLoGin panic!("sleep error: {:?}", e); 401496ba7bSLoGin }); 411496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 42151251b5Slogin drop(guard); 43151251b5Slogin sched(); 44151251b5Slogin } 45151251b5Slogin 46f678331aShanjiezhou /// @brief 让当前进程在等待队列上进行等待,并且,在释放waitqueue的锁之前,执行f函数闭包 47f678331aShanjiezhou pub fn sleep_with_func<F>(&self, f: F) 48f678331aShanjiezhou where 49f678331aShanjiezhou F: FnOnce(), 50f678331aShanjiezhou { 5140609970SGnoCiYeH before_sleep_check(0); 52f678331aShanjiezhou let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 531496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 541496ba7bSLoGin ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 551496ba7bSLoGin panic!("sleep error: {:?}", e); 561496ba7bSLoGin }); 571496ba7bSLoGin drop(irq_guard); 581496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 59f678331aShanjiezhou f(); 602f6f547aSGnoCiYeH 61f678331aShanjiezhou drop(guard); 62f678331aShanjiezhou sched(); 63f678331aShanjiezhou } 64f678331aShanjiezhou 65f678331aShanjiezhou /// @brief 让当前进程在等待队列上进行等待. 但是,在释放waitqueue的锁之后,不会调用调度函数。 66f678331aShanjiezhou /// 这样的设计,是为了让调用者可以在执行本函数之后,执行一些操作,然后再【手动调用调度函数】。 67f678331aShanjiezhou /// 68f678331aShanjiezhou /// 执行本函数前,需要确保处于【中断禁止】状态。 69f678331aShanjiezhou /// 70f678331aShanjiezhou /// 尽管sleep_with_func和sleep_without_schedule都可以实现这个功能,但是,sleep_with_func会在释放锁之前,执行f函数闭包。 71f678331aShanjiezhou /// 72f678331aShanjiezhou /// 考虑这样一个场景: 73f678331aShanjiezhou /// 等待队列位于某个自旋锁保护的数据结构A中,我们希望在进程睡眠的同时,释放数据结构A的锁。 74f678331aShanjiezhou /// 在这种情况下,如果使用sleep_with_func,所有权系统不会允许我们这么做。 75f678331aShanjiezhou /// 因此,sleep_without_schedule的设计,正是为了解决这个问题。 76f678331aShanjiezhou /// 77f678331aShanjiezhou /// 由于sleep_without_schedule不会调用调度函数,因此,如果开发者忘记在执行本函数之后,手动调用调度函数, 78f678331aShanjiezhou /// 由于时钟中断到来或者‘其他cpu kick了当前cpu’,可能会导致一些未定义的行为。 79f678331aShanjiezhou pub unsafe fn sleep_without_schedule(&self) { 8040609970SGnoCiYeH before_sleep_check(1); 81f678331aShanjiezhou // 安全检查:确保当前处于中断禁止状态 82*b5b571e0SLoGin assert!(!CurrentIrqArch::is_irq_enabled()); 83f678331aShanjiezhou let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 841496ba7bSLoGin ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 851496ba7bSLoGin panic!("sleep error: {:?}", e); 861496ba7bSLoGin }); 871496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 881496ba7bSLoGin drop(guard); 891496ba7bSLoGin } 901496ba7bSLoGin 911496ba7bSLoGin pub unsafe fn sleep_without_schedule_uninterruptible(&self) { 928cb2e9b3SLoGin before_sleep_check(1); 931496ba7bSLoGin // 安全检查:确保当前处于中断禁止状态 94*b5b571e0SLoGin assert!(!CurrentIrqArch::is_irq_enabled()); 951496ba7bSLoGin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 961496ba7bSLoGin ProcessManager::mark_sleep(false).unwrap_or_else(|e| { 971496ba7bSLoGin panic!("sleep error: {:?}", e); 981496ba7bSLoGin }); 991496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 100f678331aShanjiezhou drop(guard); 101f678331aShanjiezhou } 102151251b5Slogin /// @brief 让当前进程在等待队列上进行等待,并且,不允许被信号打断 103151251b5Slogin pub fn sleep_uninterruptible(&self) { 10440609970SGnoCiYeH before_sleep_check(0); 105151251b5Slogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 1061496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 1071496ba7bSLoGin ProcessManager::mark_sleep(false).unwrap_or_else(|e| { 1081496ba7bSLoGin panic!("sleep error: {:?}", e); 1091496ba7bSLoGin }); 1101496ba7bSLoGin drop(irq_guard); 1111496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 112151251b5Slogin drop(guard); 113151251b5Slogin sched(); 114151251b5Slogin } 115151251b5Slogin 116151251b5Slogin /// @brief 让当前进程在等待队列上进行等待,并且,允许被信号打断。 117151251b5Slogin /// 在当前进程的pcb加入队列后,解锁指定的自旋锁。 118151251b5Slogin pub fn sleep_unlock_spinlock<T>(&self, to_unlock: SpinLockGuard<T>) { 11940609970SGnoCiYeH before_sleep_check(1); 120151251b5Slogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 1211496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 1221496ba7bSLoGin ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 1231496ba7bSLoGin panic!("sleep error: {:?}", e); 1241496ba7bSLoGin }); 1251496ba7bSLoGin drop(irq_guard); 1261496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 127151251b5Slogin drop(to_unlock); 128151251b5Slogin drop(guard); 129151251b5Slogin sched(); 130151251b5Slogin } 131151251b5Slogin 132151251b5Slogin /// @brief 让当前进程在等待队列上进行等待,并且,允许被信号打断。 133151251b5Slogin /// 在当前进程的pcb加入队列后,解锁指定的Mutex。 134151251b5Slogin pub fn sleep_unlock_mutex<T>(&self, to_unlock: MutexGuard<T>) { 13540609970SGnoCiYeH before_sleep_check(1); 136151251b5Slogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 1371496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 1381496ba7bSLoGin ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 1391496ba7bSLoGin panic!("sleep error: {:?}", e); 1401496ba7bSLoGin }); 1411496ba7bSLoGin drop(irq_guard); 1421496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 143151251b5Slogin drop(to_unlock); 144151251b5Slogin drop(guard); 145151251b5Slogin sched(); 146151251b5Slogin } 147151251b5Slogin 148151251b5Slogin /// @brief 让当前进程在等待队列上进行等待,并且,不允许被信号打断。 149151251b5Slogin /// 在当前进程的pcb加入队列后,解锁指定的自旋锁。 150151251b5Slogin pub fn sleep_uninterruptible_unlock_spinlock<T>(&self, to_unlock: SpinLockGuard<T>) { 15140609970SGnoCiYeH before_sleep_check(1); 152151251b5Slogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 1531496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 1541496ba7bSLoGin ProcessManager::mark_sleep(false).unwrap_or_else(|e| { 1551496ba7bSLoGin panic!("sleep error: {:?}", e); 1561496ba7bSLoGin }); 1571496ba7bSLoGin drop(irq_guard); 1581496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 159151251b5Slogin drop(to_unlock); 160151251b5Slogin drop(guard); 161151251b5Slogin sched(); 162151251b5Slogin } 163151251b5Slogin 164151251b5Slogin /// @brief 让当前进程在等待队列上进行等待,并且,不允许被信号打断。 165151251b5Slogin /// 在当前进程的pcb加入队列后,解锁指定的Mutex。 166151251b5Slogin pub fn sleep_uninterruptible_unlock_mutex<T>(&self, to_unlock: MutexGuard<T>) { 16740609970SGnoCiYeH before_sleep_check(1); 168151251b5Slogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 1691496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 1701496ba7bSLoGin ProcessManager::mark_sleep(false).unwrap_or_else(|e| { 1711496ba7bSLoGin panic!("sleep error: {:?}", e); 1721496ba7bSLoGin }); 1731496ba7bSLoGin drop(irq_guard); 1741496ba7bSLoGin 1751496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 1761496ba7bSLoGin 177151251b5Slogin drop(to_unlock); 178151251b5Slogin drop(guard); 179151251b5Slogin sched(); 180151251b5Slogin } 181151251b5Slogin 182151251b5Slogin /// @brief 唤醒在队列中等待的第一个进程。 183151251b5Slogin /// 如果这个进程的state与给定的state进行and操作之后,结果不为0,则唤醒它。 184151251b5Slogin /// 1851496ba7bSLoGin /// @param state 用于判断的state,如果队列第一个进程与这个state相同,或者为None(表示不进行这个判断),则唤醒这个进程。 186151251b5Slogin /// 187151251b5Slogin /// @return true 成功唤醒进程 188151251b5Slogin /// @return false 没有唤醒进程 1891496ba7bSLoGin pub fn wakeup(&self, state: Option<ProcessState>) -> bool { 1900d6cf65aSLoGin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock_irqsave(); 191151251b5Slogin // 如果队列为空,则返回 192151251b5Slogin if guard.wait_list.is_empty() { 193151251b5Slogin return false; 194151251b5Slogin } 195151251b5Slogin // 如果队列头部的pcb的state与给定的state相与,结果不为0,则唤醒 1961496ba7bSLoGin if let Some(state) = state { 1970d6cf65aSLoGin if guard 1980d6cf65aSLoGin .wait_list 1990d6cf65aSLoGin .front() 2000d6cf65aSLoGin .unwrap() 2010d6cf65aSLoGin .sched_info() 2020d6cf65aSLoGin .inner_lock_read_irqsave() 2030d6cf65aSLoGin .state() 2040d6cf65aSLoGin != state 2050d6cf65aSLoGin { 206151251b5Slogin return false; 207151251b5Slogin } 208151251b5Slogin } 2091496ba7bSLoGin let to_wakeup = guard.wait_list.pop_front().unwrap(); 2100d6cf65aSLoGin drop(guard); 2111496ba7bSLoGin let res = ProcessManager::wakeup(&to_wakeup).is_ok(); 2121496ba7bSLoGin return res; 2131496ba7bSLoGin } 214151251b5Slogin 215cde5492fSlogin /// @brief 唤醒在队列中,符合条件的所有进程。 216cde5492fSlogin /// 2171496ba7bSLoGin /// @param state 用于判断的state,如果一个进程与这个state相同,或者为None(表示不进行这个判断),则唤醒这个进程。 2181496ba7bSLoGin pub fn wakeup_all(&self, state: Option<ProcessState>) { 219cde5492fSlogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock_irqsave(); 220cde5492fSlogin // 如果队列为空,则返回 221cde5492fSlogin if guard.wait_list.is_empty() { 222cde5492fSlogin return; 223cde5492fSlogin } 224cde5492fSlogin 2251496ba7bSLoGin let mut to_push_back: Vec<Arc<ProcessControlBlock>> = Vec::new(); 226cde5492fSlogin // 如果队列头部的pcb的state与给定的state相与,结果不为0,则唤醒 227cde5492fSlogin while let Some(to_wakeup) = guard.wait_list.pop_front() { 228a03c4f9dSLoGin let mut wake = false; 2291496ba7bSLoGin if let Some(state) = state { 2300d6cf65aSLoGin if to_wakeup.sched_info().inner_lock_read_irqsave().state() == state { 231a03c4f9dSLoGin wake = true; 232a03c4f9dSLoGin } 233a03c4f9dSLoGin } else { 234a03c4f9dSLoGin wake = true; 235a03c4f9dSLoGin } 236a03c4f9dSLoGin 237a03c4f9dSLoGin if wake { 2381496ba7bSLoGin ProcessManager::wakeup(&to_wakeup).unwrap_or_else(|e| { 2391496ba7bSLoGin kerror!("wakeup pid: {:?} error: {:?}", to_wakeup.pid(), e); 2401496ba7bSLoGin }); 2411496ba7bSLoGin continue; 242a03c4f9dSLoGin } else { 243cde5492fSlogin to_push_back.push(to_wakeup); 244cde5492fSlogin } 245a03c4f9dSLoGin } 246a03c4f9dSLoGin 247cde5492fSlogin for to_wakeup in to_push_back { 248cde5492fSlogin guard.wait_list.push_back(to_wakeup); 249cde5492fSlogin } 250cde5492fSlogin } 251cde5492fSlogin 252151251b5Slogin /// @brief 获得当前等待队列的大小 253151251b5Slogin pub fn len(&self) -> usize { 254151251b5Slogin return self.0.lock().wait_list.len(); 255151251b5Slogin } 256151251b5Slogin } 257151251b5Slogin 258151251b5Slogin impl InnerWaitQueue { 259151251b5Slogin pub const INIT: InnerWaitQueue = InnerWaitQueue { 260151251b5Slogin wait_list: LinkedList::new(), 261151251b5Slogin }; 262151251b5Slogin } 26340609970SGnoCiYeH 26440609970SGnoCiYeH fn before_sleep_check(max_preempt: usize) { 26540609970SGnoCiYeH let pcb = ProcessManager::current_pcb(); 26640609970SGnoCiYeH if unlikely(pcb.preempt_count() > max_preempt) { 26740609970SGnoCiYeH kwarn!( 26840609970SGnoCiYeH "Process {:?}: Try to sleep when preempt count is {}", 2698cb2e9b3SLoGin pcb.pid().data(), 27040609970SGnoCiYeH pcb.preempt_count() 27140609970SGnoCiYeH ); 27240609970SGnoCiYeH } 27340609970SGnoCiYeH } 27440609970SGnoCiYeH 27540609970SGnoCiYeH /// 事件等待队列 27640609970SGnoCiYeH #[derive(Debug)] 27740609970SGnoCiYeH pub struct EventWaitQueue { 27840609970SGnoCiYeH wait_list: SpinLock<Vec<(u64, Arc<ProcessControlBlock>)>>, 27940609970SGnoCiYeH } 28040609970SGnoCiYeH 281e2841179SLoGin #[allow(dead_code)] 28240609970SGnoCiYeH impl EventWaitQueue { 28340609970SGnoCiYeH pub fn new() -> Self { 28440609970SGnoCiYeH Self { 28540609970SGnoCiYeH wait_list: SpinLock::new(Vec::new()), 28640609970SGnoCiYeH } 28740609970SGnoCiYeH } 28840609970SGnoCiYeH 28940609970SGnoCiYeH /// ## 让当前进程在该队列上等待感兴趣的事件 29040609970SGnoCiYeH /// 29140609970SGnoCiYeH /// ### 参数 29240609970SGnoCiYeH /// - events: 进程感兴趣的事件,events最好是为位表示,一位表示一个事件 29340609970SGnoCiYeH /// 29440609970SGnoCiYeH /// 注意,使用前应该注意有可能其他地方定义了冲突的事件,可能会导致未定义行为 29540609970SGnoCiYeH pub fn sleep(&self, events: u64) { 29640609970SGnoCiYeH before_sleep_check(0); 29740609970SGnoCiYeH let mut guard = self.wait_list.lock_irqsave(); 29840609970SGnoCiYeH ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 29940609970SGnoCiYeH panic!("sleep error: {:?}", e); 30040609970SGnoCiYeH }); 30140609970SGnoCiYeH guard.push((events, ProcessManager::current_pcb())); 30240609970SGnoCiYeH drop(guard); 30340609970SGnoCiYeH sched(); 30440609970SGnoCiYeH } 30540609970SGnoCiYeH 30640609970SGnoCiYeH pub unsafe fn sleep_without_schedule(&self, events: u64) { 30740609970SGnoCiYeH before_sleep_check(1); 30840609970SGnoCiYeH let mut guard = self.wait_list.lock_irqsave(); 30940609970SGnoCiYeH ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 31040609970SGnoCiYeH panic!("sleep error: {:?}", e); 31140609970SGnoCiYeH }); 31240609970SGnoCiYeH guard.push((events, ProcessManager::current_pcb())); 31340609970SGnoCiYeH drop(guard); 31440609970SGnoCiYeH } 31540609970SGnoCiYeH 31640609970SGnoCiYeH pub fn sleep_unlock_spinlock<T>(&self, events: u64, to_unlock: SpinLockGuard<T>) { 31740609970SGnoCiYeH before_sleep_check(1); 3180d6cf65aSLoGin let mut guard = self.wait_list.lock_irqsave(); 31940609970SGnoCiYeH let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 32040609970SGnoCiYeH ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 32140609970SGnoCiYeH panic!("sleep error: {:?}", e); 32240609970SGnoCiYeH }); 32340609970SGnoCiYeH drop(irq_guard); 32440609970SGnoCiYeH guard.push((events, ProcessManager::current_pcb())); 32540609970SGnoCiYeH drop(to_unlock); 32640609970SGnoCiYeH drop(guard); 32740609970SGnoCiYeH sched(); 32840609970SGnoCiYeH } 32940609970SGnoCiYeH 33040609970SGnoCiYeH /// ### 唤醒该队列上等待events的进程 33140609970SGnoCiYeH /// 33240609970SGnoCiYeH /// ### 参数 33340609970SGnoCiYeH /// - events: 发生的事件 33440609970SGnoCiYeH /// 33540609970SGnoCiYeH /// 需要注意的是,只要触发了events中的任意一件事件,进程都会被唤醒 33640609970SGnoCiYeH pub fn wakeup_any(&self, events: u64) -> usize { 33740609970SGnoCiYeH let mut ret = 0; 3380d6cf65aSLoGin 3390d6cf65aSLoGin let mut wq_guard = self.wait_list.lock_irqsave(); 3400d6cf65aSLoGin wq_guard.retain(|(es, pcb)| { 34140609970SGnoCiYeH if *es & events > 0 { 34240609970SGnoCiYeH // 有感兴趣的事件 34340609970SGnoCiYeH if ProcessManager::wakeup(pcb).is_ok() { 34440609970SGnoCiYeH ret += 1; 34540609970SGnoCiYeH return false; 3460e7c4693SGnoCiYeH } else { 3470e7c4693SGnoCiYeH return true; 34840609970SGnoCiYeH } 34940609970SGnoCiYeH } else { 3500e7c4693SGnoCiYeH return true; 35140609970SGnoCiYeH } 35240609970SGnoCiYeH }); 35340609970SGnoCiYeH ret 35440609970SGnoCiYeH } 35540609970SGnoCiYeH 35640609970SGnoCiYeH /// ### 唤醒该队列上等待events的进程 35740609970SGnoCiYeH /// 35840609970SGnoCiYeH /// ### 参数 35940609970SGnoCiYeH /// - events: 发生的事件 36040609970SGnoCiYeH /// 36140609970SGnoCiYeH /// 需要注意的是,只有满足所有事件的进程才会被唤醒 36240609970SGnoCiYeH pub fn wakeup(&self, events: u64) -> usize { 36340609970SGnoCiYeH let mut ret = 0; 3640d6cf65aSLoGin let mut wq_guard = self.wait_list.lock_irqsave(); 3650d6cf65aSLoGin wq_guard.retain(|(es, pcb)| { 36640609970SGnoCiYeH if *es == events { 36740609970SGnoCiYeH // 有感兴趣的事件 36840609970SGnoCiYeH if ProcessManager::wakeup(pcb).is_ok() { 36940609970SGnoCiYeH ret += 1; 37040609970SGnoCiYeH return false; 3710e7c4693SGnoCiYeH } else { 3720e7c4693SGnoCiYeH return true; 37340609970SGnoCiYeH } 37440609970SGnoCiYeH } else { 3750e7c4693SGnoCiYeH return true; 37640609970SGnoCiYeH } 37740609970SGnoCiYeH }); 37840609970SGnoCiYeH ret 37940609970SGnoCiYeH } 38040609970SGnoCiYeH 38140609970SGnoCiYeH pub fn wakeup_all(&self) { 38240609970SGnoCiYeH self.wakeup_any(u64::MAX); 38340609970SGnoCiYeH } 38440609970SGnoCiYeH } 385