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 { 30151251b5Slogin pub const INIT: WaitQueue = WaitQueue(SpinLock::new(InnerWaitQueue::INIT)); 31151251b5Slogin 32151251b5Slogin /// @brief 让当前进程在等待队列上进行等待,并且,允许被信号打断 33151251b5Slogin pub fn sleep(&self) { 3440609970SGnoCiYeH before_sleep_check(0); 351496ba7bSLoGin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock_irqsave(); 361496ba7bSLoGin ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 371496ba7bSLoGin panic!("sleep error: {:?}", e); 381496ba7bSLoGin }); 391496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 40151251b5Slogin drop(guard); 41151251b5Slogin sched(); 42151251b5Slogin } 43151251b5Slogin 44f678331aShanjiezhou /// @brief 让当前进程在等待队列上进行等待,并且,在释放waitqueue的锁之前,执行f函数闭包 45f678331aShanjiezhou pub fn sleep_with_func<F>(&self, f: F) 46f678331aShanjiezhou where 47f678331aShanjiezhou F: FnOnce(), 48f678331aShanjiezhou { 4940609970SGnoCiYeH before_sleep_check(0); 50f678331aShanjiezhou let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 511496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 521496ba7bSLoGin ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 531496ba7bSLoGin panic!("sleep error: {:?}", e); 541496ba7bSLoGin }); 551496ba7bSLoGin drop(irq_guard); 561496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 57f678331aShanjiezhou f(); 582f6f547aSGnoCiYeH 59f678331aShanjiezhou drop(guard); 60f678331aShanjiezhou sched(); 61f678331aShanjiezhou } 62f678331aShanjiezhou 63f678331aShanjiezhou /// @brief 让当前进程在等待队列上进行等待. 但是,在释放waitqueue的锁之后,不会调用调度函数。 64f678331aShanjiezhou /// 这样的设计,是为了让调用者可以在执行本函数之后,执行一些操作,然后再【手动调用调度函数】。 65f678331aShanjiezhou /// 66f678331aShanjiezhou /// 执行本函数前,需要确保处于【中断禁止】状态。 67f678331aShanjiezhou /// 68f678331aShanjiezhou /// 尽管sleep_with_func和sleep_without_schedule都可以实现这个功能,但是,sleep_with_func会在释放锁之前,执行f函数闭包。 69f678331aShanjiezhou /// 70f678331aShanjiezhou /// 考虑这样一个场景: 71f678331aShanjiezhou /// 等待队列位于某个自旋锁保护的数据结构A中,我们希望在进程睡眠的同时,释放数据结构A的锁。 72f678331aShanjiezhou /// 在这种情况下,如果使用sleep_with_func,所有权系统不会允许我们这么做。 73f678331aShanjiezhou /// 因此,sleep_without_schedule的设计,正是为了解决这个问题。 74f678331aShanjiezhou /// 75f678331aShanjiezhou /// 由于sleep_without_schedule不会调用调度函数,因此,如果开发者忘记在执行本函数之后,手动调用调度函数, 76f678331aShanjiezhou /// 由于时钟中断到来或者‘其他cpu kick了当前cpu’,可能会导致一些未定义的行为。 77f678331aShanjiezhou pub unsafe fn sleep_without_schedule(&self) { 7840609970SGnoCiYeH before_sleep_check(1); 79f678331aShanjiezhou // 安全检查:确保当前处于中断禁止状态 80f678331aShanjiezhou assert!(CurrentIrqArch::is_irq_enabled() == false); 81f678331aShanjiezhou let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 821496ba7bSLoGin ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 831496ba7bSLoGin panic!("sleep error: {:?}", e); 841496ba7bSLoGin }); 851496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 861496ba7bSLoGin drop(guard); 871496ba7bSLoGin } 881496ba7bSLoGin 891496ba7bSLoGin pub unsafe fn sleep_without_schedule_uninterruptible(&self) { 90*8cb2e9b3SLoGin before_sleep_check(1); 911496ba7bSLoGin // 安全检查:确保当前处于中断禁止状态 921496ba7bSLoGin assert!(CurrentIrqArch::is_irq_enabled() == false); 931496ba7bSLoGin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 941496ba7bSLoGin ProcessManager::mark_sleep(false).unwrap_or_else(|e| { 951496ba7bSLoGin panic!("sleep error: {:?}", e); 961496ba7bSLoGin }); 971496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 98f678331aShanjiezhou drop(guard); 99f678331aShanjiezhou } 100151251b5Slogin /// @brief 让当前进程在等待队列上进行等待,并且,不允许被信号打断 101151251b5Slogin pub fn sleep_uninterruptible(&self) { 10240609970SGnoCiYeH before_sleep_check(0); 103151251b5Slogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 1041496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 1051496ba7bSLoGin ProcessManager::mark_sleep(false).unwrap_or_else(|e| { 1061496ba7bSLoGin panic!("sleep error: {:?}", e); 1071496ba7bSLoGin }); 1081496ba7bSLoGin drop(irq_guard); 1091496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 110151251b5Slogin drop(guard); 111151251b5Slogin sched(); 112151251b5Slogin } 113151251b5Slogin 114151251b5Slogin /// @brief 让当前进程在等待队列上进行等待,并且,允许被信号打断。 115151251b5Slogin /// 在当前进程的pcb加入队列后,解锁指定的自旋锁。 116151251b5Slogin pub fn sleep_unlock_spinlock<T>(&self, to_unlock: SpinLockGuard<T>) { 11740609970SGnoCiYeH before_sleep_check(1); 118151251b5Slogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 1191496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 1201496ba7bSLoGin ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 1211496ba7bSLoGin panic!("sleep error: {:?}", e); 1221496ba7bSLoGin }); 1231496ba7bSLoGin drop(irq_guard); 1241496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 125151251b5Slogin drop(to_unlock); 126151251b5Slogin drop(guard); 127151251b5Slogin sched(); 128151251b5Slogin } 129151251b5Slogin 130151251b5Slogin /// @brief 让当前进程在等待队列上进行等待,并且,允许被信号打断。 131151251b5Slogin /// 在当前进程的pcb加入队列后,解锁指定的Mutex。 132151251b5Slogin pub fn sleep_unlock_mutex<T>(&self, to_unlock: MutexGuard<T>) { 13340609970SGnoCiYeH before_sleep_check(1); 134151251b5Slogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 1351496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 1361496ba7bSLoGin ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 1371496ba7bSLoGin panic!("sleep error: {:?}", e); 1381496ba7bSLoGin }); 1391496ba7bSLoGin drop(irq_guard); 1401496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 141151251b5Slogin drop(to_unlock); 142151251b5Slogin drop(guard); 143151251b5Slogin sched(); 144151251b5Slogin } 145151251b5Slogin 146151251b5Slogin /// @brief 让当前进程在等待队列上进行等待,并且,不允许被信号打断。 147151251b5Slogin /// 在当前进程的pcb加入队列后,解锁指定的自旋锁。 148151251b5Slogin pub fn sleep_uninterruptible_unlock_spinlock<T>(&self, to_unlock: SpinLockGuard<T>) { 14940609970SGnoCiYeH before_sleep_check(1); 150151251b5Slogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 1511496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 1521496ba7bSLoGin ProcessManager::mark_sleep(false).unwrap_or_else(|e| { 1531496ba7bSLoGin panic!("sleep error: {:?}", e); 1541496ba7bSLoGin }); 1551496ba7bSLoGin drop(irq_guard); 1561496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 157151251b5Slogin drop(to_unlock); 158151251b5Slogin drop(guard); 159151251b5Slogin sched(); 160151251b5Slogin } 161151251b5Slogin 162151251b5Slogin /// @brief 让当前进程在等待队列上进行等待,并且,不允许被信号打断。 163151251b5Slogin /// 在当前进程的pcb加入队列后,解锁指定的Mutex。 164151251b5Slogin pub fn sleep_uninterruptible_unlock_mutex<T>(&self, to_unlock: MutexGuard<T>) { 16540609970SGnoCiYeH before_sleep_check(1); 166151251b5Slogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 1671496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 1681496ba7bSLoGin ProcessManager::mark_sleep(false).unwrap_or_else(|e| { 1691496ba7bSLoGin panic!("sleep error: {:?}", e); 1701496ba7bSLoGin }); 1711496ba7bSLoGin drop(irq_guard); 1721496ba7bSLoGin 1731496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 1741496ba7bSLoGin 175151251b5Slogin drop(to_unlock); 176151251b5Slogin drop(guard); 177151251b5Slogin sched(); 178151251b5Slogin } 179151251b5Slogin 180151251b5Slogin /// @brief 唤醒在队列中等待的第一个进程。 181151251b5Slogin /// 如果这个进程的state与给定的state进行and操作之后,结果不为0,则唤醒它。 182151251b5Slogin /// 1831496ba7bSLoGin /// @param state 用于判断的state,如果队列第一个进程与这个state相同,或者为None(表示不进行这个判断),则唤醒这个进程。 184151251b5Slogin /// 185151251b5Slogin /// @return true 成功唤醒进程 186151251b5Slogin /// @return false 没有唤醒进程 1871496ba7bSLoGin pub fn wakeup(&self, state: Option<ProcessState>) -> bool { 1880d6cf65aSLoGin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock_irqsave(); 189151251b5Slogin // 如果队列为空,则返回 190151251b5Slogin if guard.wait_list.is_empty() { 191151251b5Slogin return false; 192151251b5Slogin } 193151251b5Slogin // 如果队列头部的pcb的state与给定的state相与,结果不为0,则唤醒 1941496ba7bSLoGin if let Some(state) = state { 1950d6cf65aSLoGin if guard 1960d6cf65aSLoGin .wait_list 1970d6cf65aSLoGin .front() 1980d6cf65aSLoGin .unwrap() 1990d6cf65aSLoGin .sched_info() 2000d6cf65aSLoGin .inner_lock_read_irqsave() 2010d6cf65aSLoGin .state() 2020d6cf65aSLoGin != state 2030d6cf65aSLoGin { 204151251b5Slogin return false; 205151251b5Slogin } 206151251b5Slogin } 2071496ba7bSLoGin let to_wakeup = guard.wait_list.pop_front().unwrap(); 2080d6cf65aSLoGin drop(guard); 2091496ba7bSLoGin let res = ProcessManager::wakeup(&to_wakeup).is_ok(); 2101496ba7bSLoGin return res; 2111496ba7bSLoGin } 212151251b5Slogin 213cde5492fSlogin /// @brief 唤醒在队列中,符合条件的所有进程。 214cde5492fSlogin /// 2151496ba7bSLoGin /// @param state 用于判断的state,如果一个进程与这个state相同,或者为None(表示不进行这个判断),则唤醒这个进程。 2161496ba7bSLoGin pub fn wakeup_all(&self, state: Option<ProcessState>) { 217cde5492fSlogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock_irqsave(); 218cde5492fSlogin // 如果队列为空,则返回 219cde5492fSlogin if guard.wait_list.is_empty() { 220cde5492fSlogin return; 221cde5492fSlogin } 222cde5492fSlogin 2231496ba7bSLoGin let mut to_push_back: Vec<Arc<ProcessControlBlock>> = Vec::new(); 224cde5492fSlogin // 如果队列头部的pcb的state与给定的state相与,结果不为0,则唤醒 225cde5492fSlogin while let Some(to_wakeup) = guard.wait_list.pop_front() { 226a03c4f9dSLoGin let mut wake = false; 2271496ba7bSLoGin if let Some(state) = state { 2280d6cf65aSLoGin if to_wakeup.sched_info().inner_lock_read_irqsave().state() == state { 229a03c4f9dSLoGin wake = true; 230a03c4f9dSLoGin } 231a03c4f9dSLoGin } else { 232a03c4f9dSLoGin wake = true; 233a03c4f9dSLoGin } 234a03c4f9dSLoGin 235a03c4f9dSLoGin if wake { 2361496ba7bSLoGin ProcessManager::wakeup(&to_wakeup).unwrap_or_else(|e| { 2371496ba7bSLoGin kerror!("wakeup pid: {:?} error: {:?}", to_wakeup.pid(), e); 2381496ba7bSLoGin }); 2391496ba7bSLoGin continue; 240a03c4f9dSLoGin } else { 241cde5492fSlogin to_push_back.push(to_wakeup); 242cde5492fSlogin } 243a03c4f9dSLoGin } 244a03c4f9dSLoGin 245cde5492fSlogin for to_wakeup in to_push_back { 246cde5492fSlogin guard.wait_list.push_back(to_wakeup); 247cde5492fSlogin } 248cde5492fSlogin } 249cde5492fSlogin 250151251b5Slogin /// @brief 获得当前等待队列的大小 251151251b5Slogin pub fn len(&self) -> usize { 252151251b5Slogin return self.0.lock().wait_list.len(); 253151251b5Slogin } 254151251b5Slogin } 255151251b5Slogin 256151251b5Slogin impl InnerWaitQueue { 257151251b5Slogin pub const INIT: InnerWaitQueue = InnerWaitQueue { 258151251b5Slogin wait_list: LinkedList::new(), 259151251b5Slogin }; 260151251b5Slogin } 26140609970SGnoCiYeH 26240609970SGnoCiYeH fn before_sleep_check(max_preempt: usize) { 26340609970SGnoCiYeH let pcb = ProcessManager::current_pcb(); 26440609970SGnoCiYeH if unlikely(pcb.preempt_count() > max_preempt) { 26540609970SGnoCiYeH kwarn!( 26640609970SGnoCiYeH "Process {:?}: Try to sleep when preempt count is {}", 267*8cb2e9b3SLoGin pcb.pid().data(), 26840609970SGnoCiYeH pcb.preempt_count() 26940609970SGnoCiYeH ); 27040609970SGnoCiYeH } 27140609970SGnoCiYeH } 27240609970SGnoCiYeH 27340609970SGnoCiYeH /// 事件等待队列 27440609970SGnoCiYeH #[derive(Debug)] 27540609970SGnoCiYeH pub struct EventWaitQueue { 27640609970SGnoCiYeH wait_list: SpinLock<Vec<(u64, Arc<ProcessControlBlock>)>>, 27740609970SGnoCiYeH } 27840609970SGnoCiYeH 279e2841179SLoGin #[allow(dead_code)] 28040609970SGnoCiYeH impl EventWaitQueue { 28140609970SGnoCiYeH pub fn new() -> Self { 28240609970SGnoCiYeH Self { 28340609970SGnoCiYeH wait_list: SpinLock::new(Vec::new()), 28440609970SGnoCiYeH } 28540609970SGnoCiYeH } 28640609970SGnoCiYeH 28740609970SGnoCiYeH /// ## 让当前进程在该队列上等待感兴趣的事件 28840609970SGnoCiYeH /// 28940609970SGnoCiYeH /// ### 参数 29040609970SGnoCiYeH /// - events: 进程感兴趣的事件,events最好是为位表示,一位表示一个事件 29140609970SGnoCiYeH /// 29240609970SGnoCiYeH /// 注意,使用前应该注意有可能其他地方定义了冲突的事件,可能会导致未定义行为 29340609970SGnoCiYeH pub fn sleep(&self, events: u64) { 29440609970SGnoCiYeH before_sleep_check(0); 29540609970SGnoCiYeH let mut guard = self.wait_list.lock_irqsave(); 29640609970SGnoCiYeH ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 29740609970SGnoCiYeH panic!("sleep error: {:?}", e); 29840609970SGnoCiYeH }); 29940609970SGnoCiYeH guard.push((events, ProcessManager::current_pcb())); 30040609970SGnoCiYeH drop(guard); 30140609970SGnoCiYeH sched(); 30240609970SGnoCiYeH } 30340609970SGnoCiYeH 30440609970SGnoCiYeH pub unsafe fn sleep_without_schedule(&self, events: u64) { 30540609970SGnoCiYeH before_sleep_check(1); 30640609970SGnoCiYeH let mut guard = self.wait_list.lock_irqsave(); 30740609970SGnoCiYeH ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 30840609970SGnoCiYeH panic!("sleep error: {:?}", e); 30940609970SGnoCiYeH }); 31040609970SGnoCiYeH guard.push((events, ProcessManager::current_pcb())); 31140609970SGnoCiYeH drop(guard); 31240609970SGnoCiYeH } 31340609970SGnoCiYeH 31440609970SGnoCiYeH pub fn sleep_unlock_spinlock<T>(&self, events: u64, to_unlock: SpinLockGuard<T>) { 31540609970SGnoCiYeH before_sleep_check(1); 3160d6cf65aSLoGin let mut guard = self.wait_list.lock_irqsave(); 31740609970SGnoCiYeH let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 31840609970SGnoCiYeH ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 31940609970SGnoCiYeH panic!("sleep error: {:?}", e); 32040609970SGnoCiYeH }); 32140609970SGnoCiYeH drop(irq_guard); 32240609970SGnoCiYeH guard.push((events, ProcessManager::current_pcb())); 32340609970SGnoCiYeH drop(to_unlock); 32440609970SGnoCiYeH drop(guard); 32540609970SGnoCiYeH sched(); 32640609970SGnoCiYeH } 32740609970SGnoCiYeH 32840609970SGnoCiYeH /// ### 唤醒该队列上等待events的进程 32940609970SGnoCiYeH /// 33040609970SGnoCiYeH /// ### 参数 33140609970SGnoCiYeH /// - events: 发生的事件 33240609970SGnoCiYeH /// 33340609970SGnoCiYeH /// 需要注意的是,只要触发了events中的任意一件事件,进程都会被唤醒 33440609970SGnoCiYeH pub fn wakeup_any(&self, events: u64) -> usize { 33540609970SGnoCiYeH let mut ret = 0; 3360d6cf65aSLoGin 3370d6cf65aSLoGin let mut wq_guard = self.wait_list.lock_irqsave(); 3380d6cf65aSLoGin wq_guard.retain(|(es, pcb)| { 33940609970SGnoCiYeH if *es & events > 0 { 34040609970SGnoCiYeH // 有感兴趣的事件 34140609970SGnoCiYeH if ProcessManager::wakeup(pcb).is_ok() { 34240609970SGnoCiYeH ret += 1; 34340609970SGnoCiYeH return false; 3440e7c4693SGnoCiYeH } else { 3450e7c4693SGnoCiYeH return true; 34640609970SGnoCiYeH } 34740609970SGnoCiYeH } else { 3480e7c4693SGnoCiYeH return true; 34940609970SGnoCiYeH } 35040609970SGnoCiYeH }); 35140609970SGnoCiYeH ret 35240609970SGnoCiYeH } 35340609970SGnoCiYeH 35440609970SGnoCiYeH /// ### 唤醒该队列上等待events的进程 35540609970SGnoCiYeH /// 35640609970SGnoCiYeH /// ### 参数 35740609970SGnoCiYeH /// - events: 发生的事件 35840609970SGnoCiYeH /// 35940609970SGnoCiYeH /// 需要注意的是,只有满足所有事件的进程才会被唤醒 36040609970SGnoCiYeH pub fn wakeup(&self, events: u64) -> usize { 36140609970SGnoCiYeH let mut ret = 0; 3620d6cf65aSLoGin let mut wq_guard = self.wait_list.lock_irqsave(); 3630d6cf65aSLoGin wq_guard.retain(|(es, pcb)| { 36440609970SGnoCiYeH if *es == events { 36540609970SGnoCiYeH // 有感兴趣的事件 36640609970SGnoCiYeH if ProcessManager::wakeup(pcb).is_ok() { 36740609970SGnoCiYeH ret += 1; 36840609970SGnoCiYeH return false; 3690e7c4693SGnoCiYeH } else { 3700e7c4693SGnoCiYeH return true; 37140609970SGnoCiYeH } 37240609970SGnoCiYeH } else { 3730e7c4693SGnoCiYeH return true; 37440609970SGnoCiYeH } 37540609970SGnoCiYeH }); 37640609970SGnoCiYeH ret 37740609970SGnoCiYeH } 37840609970SGnoCiYeH 37940609970SGnoCiYeH pub fn wakeup_all(&self) { 38040609970SGnoCiYeH self.wakeup_any(u64::MAX); 38140609970SGnoCiYeH } 38240609970SGnoCiYeH } 383