1151251b5Slogin #![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 28151251b5Slogin impl WaitQueue { 29151251b5Slogin pub const INIT: WaitQueue = WaitQueue(SpinLock::new(InnerWaitQueue::INIT)); 30151251b5Slogin 31151251b5Slogin /// @brief 让当前进程在等待队列上进行等待,并且,允许被信号打断 32151251b5Slogin pub fn sleep(&self) { 3340609970SGnoCiYeH before_sleep_check(0); 341496ba7bSLoGin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock_irqsave(); 351496ba7bSLoGin ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 361496ba7bSLoGin panic!("sleep error: {:?}", e); 371496ba7bSLoGin }); 381496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 39151251b5Slogin drop(guard); 40151251b5Slogin sched(); 41151251b5Slogin } 42151251b5Slogin 43f678331aShanjiezhou /// @brief 让当前进程在等待队列上进行等待,并且,在释放waitqueue的锁之前,执行f函数闭包 44f678331aShanjiezhou pub fn sleep_with_func<F>(&self, f: F) 45f678331aShanjiezhou where 46f678331aShanjiezhou F: FnOnce(), 47f678331aShanjiezhou { 4840609970SGnoCiYeH before_sleep_check(0); 49f678331aShanjiezhou let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 501496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 511496ba7bSLoGin ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 521496ba7bSLoGin panic!("sleep error: {:?}", e); 531496ba7bSLoGin }); 541496ba7bSLoGin drop(irq_guard); 551496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 56f678331aShanjiezhou f(); 572f6f547aSGnoCiYeH 58f678331aShanjiezhou drop(guard); 59f678331aShanjiezhou sched(); 60f678331aShanjiezhou } 61f678331aShanjiezhou 62f678331aShanjiezhou /// @brief 让当前进程在等待队列上进行等待. 但是,在释放waitqueue的锁之后,不会调用调度函数。 63f678331aShanjiezhou /// 这样的设计,是为了让调用者可以在执行本函数之后,执行一些操作,然后再【手动调用调度函数】。 64f678331aShanjiezhou /// 65f678331aShanjiezhou /// 执行本函数前,需要确保处于【中断禁止】状态。 66f678331aShanjiezhou /// 67f678331aShanjiezhou /// 尽管sleep_with_func和sleep_without_schedule都可以实现这个功能,但是,sleep_with_func会在释放锁之前,执行f函数闭包。 68f678331aShanjiezhou /// 69f678331aShanjiezhou /// 考虑这样一个场景: 70f678331aShanjiezhou /// 等待队列位于某个自旋锁保护的数据结构A中,我们希望在进程睡眠的同时,释放数据结构A的锁。 71f678331aShanjiezhou /// 在这种情况下,如果使用sleep_with_func,所有权系统不会允许我们这么做。 72f678331aShanjiezhou /// 因此,sleep_without_schedule的设计,正是为了解决这个问题。 73f678331aShanjiezhou /// 74f678331aShanjiezhou /// 由于sleep_without_schedule不会调用调度函数,因此,如果开发者忘记在执行本函数之后,手动调用调度函数, 75f678331aShanjiezhou /// 由于时钟中断到来或者‘其他cpu kick了当前cpu’,可能会导致一些未定义的行为。 76f678331aShanjiezhou pub unsafe fn sleep_without_schedule(&self) { 7740609970SGnoCiYeH before_sleep_check(1); 78f678331aShanjiezhou // 安全检查:确保当前处于中断禁止状态 79f678331aShanjiezhou assert!(CurrentIrqArch::is_irq_enabled() == false); 80f678331aShanjiezhou let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 811496ba7bSLoGin ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 821496ba7bSLoGin panic!("sleep error: {:?}", e); 831496ba7bSLoGin }); 841496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 851496ba7bSLoGin drop(guard); 861496ba7bSLoGin } 871496ba7bSLoGin 881496ba7bSLoGin pub unsafe fn sleep_without_schedule_uninterruptible(&self) { 8940609970SGnoCiYeH before_sleep_check(0); 901496ba7bSLoGin // 安全检查:确保当前处于中断禁止状态 911496ba7bSLoGin assert!(CurrentIrqArch::is_irq_enabled() == false); 921496ba7bSLoGin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 931496ba7bSLoGin ProcessManager::mark_sleep(false).unwrap_or_else(|e| { 941496ba7bSLoGin panic!("sleep error: {:?}", e); 951496ba7bSLoGin }); 961496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 97f678331aShanjiezhou drop(guard); 98f678331aShanjiezhou } 99151251b5Slogin /// @brief 让当前进程在等待队列上进行等待,并且,不允许被信号打断 100151251b5Slogin pub fn sleep_uninterruptible(&self) { 10140609970SGnoCiYeH before_sleep_check(0); 102151251b5Slogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 1031496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 1041496ba7bSLoGin ProcessManager::mark_sleep(false).unwrap_or_else(|e| { 1051496ba7bSLoGin panic!("sleep error: {:?}", e); 1061496ba7bSLoGin }); 1071496ba7bSLoGin drop(irq_guard); 1081496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 109151251b5Slogin drop(guard); 110151251b5Slogin sched(); 111151251b5Slogin } 112151251b5Slogin 113151251b5Slogin /// @brief 让当前进程在等待队列上进行等待,并且,允许被信号打断。 114151251b5Slogin /// 在当前进程的pcb加入队列后,解锁指定的自旋锁。 115151251b5Slogin pub fn sleep_unlock_spinlock<T>(&self, to_unlock: SpinLockGuard<T>) { 11640609970SGnoCiYeH before_sleep_check(1); 117151251b5Slogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 1181496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 1191496ba7bSLoGin ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 1201496ba7bSLoGin panic!("sleep error: {:?}", e); 1211496ba7bSLoGin }); 1221496ba7bSLoGin drop(irq_guard); 1231496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 124151251b5Slogin drop(to_unlock); 125151251b5Slogin drop(guard); 126151251b5Slogin sched(); 127151251b5Slogin } 128151251b5Slogin 129151251b5Slogin /// @brief 让当前进程在等待队列上进行等待,并且,允许被信号打断。 130151251b5Slogin /// 在当前进程的pcb加入队列后,解锁指定的Mutex。 131151251b5Slogin pub fn sleep_unlock_mutex<T>(&self, to_unlock: MutexGuard<T>) { 13240609970SGnoCiYeH before_sleep_check(1); 133151251b5Slogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 1341496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 1351496ba7bSLoGin ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 1361496ba7bSLoGin panic!("sleep error: {:?}", e); 1371496ba7bSLoGin }); 1381496ba7bSLoGin drop(irq_guard); 1391496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 140151251b5Slogin drop(to_unlock); 141151251b5Slogin drop(guard); 142151251b5Slogin sched(); 143151251b5Slogin } 144151251b5Slogin 145151251b5Slogin /// @brief 让当前进程在等待队列上进行等待,并且,不允许被信号打断。 146151251b5Slogin /// 在当前进程的pcb加入队列后,解锁指定的自旋锁。 147151251b5Slogin pub fn sleep_uninterruptible_unlock_spinlock<T>(&self, to_unlock: SpinLockGuard<T>) { 14840609970SGnoCiYeH before_sleep_check(1); 149151251b5Slogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 1501496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 1511496ba7bSLoGin ProcessManager::mark_sleep(false).unwrap_or_else(|e| { 1521496ba7bSLoGin panic!("sleep error: {:?}", e); 1531496ba7bSLoGin }); 1541496ba7bSLoGin drop(irq_guard); 1551496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 156151251b5Slogin drop(to_unlock); 157151251b5Slogin drop(guard); 158151251b5Slogin sched(); 159151251b5Slogin } 160151251b5Slogin 161151251b5Slogin /// @brief 让当前进程在等待队列上进行等待,并且,不允许被信号打断。 162151251b5Slogin /// 在当前进程的pcb加入队列后,解锁指定的Mutex。 163151251b5Slogin pub fn sleep_uninterruptible_unlock_mutex<T>(&self, to_unlock: MutexGuard<T>) { 16440609970SGnoCiYeH before_sleep_check(1); 165151251b5Slogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 1661496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 1671496ba7bSLoGin ProcessManager::mark_sleep(false).unwrap_or_else(|e| { 1681496ba7bSLoGin panic!("sleep error: {:?}", e); 1691496ba7bSLoGin }); 1701496ba7bSLoGin drop(irq_guard); 1711496ba7bSLoGin 1721496ba7bSLoGin guard.wait_list.push_back(ProcessManager::current_pcb()); 1731496ba7bSLoGin 174151251b5Slogin drop(to_unlock); 175151251b5Slogin drop(guard); 176151251b5Slogin sched(); 177151251b5Slogin } 178151251b5Slogin 179151251b5Slogin /// @brief 唤醒在队列中等待的第一个进程。 180151251b5Slogin /// 如果这个进程的state与给定的state进行and操作之后,结果不为0,则唤醒它。 181151251b5Slogin /// 1821496ba7bSLoGin /// @param state 用于判断的state,如果队列第一个进程与这个state相同,或者为None(表示不进行这个判断),则唤醒这个进程。 183151251b5Slogin /// 184151251b5Slogin /// @return true 成功唤醒进程 185151251b5Slogin /// @return false 没有唤醒进程 1861496ba7bSLoGin pub fn wakeup(&self, state: Option<ProcessState>) -> bool { 187*0d6cf65aSLoGin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock_irqsave(); 188151251b5Slogin // 如果队列为空,则返回 189151251b5Slogin if guard.wait_list.is_empty() { 190151251b5Slogin return false; 191151251b5Slogin } 192151251b5Slogin // 如果队列头部的pcb的state与给定的state相与,结果不为0,则唤醒 1931496ba7bSLoGin if let Some(state) = state { 194*0d6cf65aSLoGin if guard 195*0d6cf65aSLoGin .wait_list 196*0d6cf65aSLoGin .front() 197*0d6cf65aSLoGin .unwrap() 198*0d6cf65aSLoGin .sched_info() 199*0d6cf65aSLoGin .inner_lock_read_irqsave() 200*0d6cf65aSLoGin .state() 201*0d6cf65aSLoGin != state 202*0d6cf65aSLoGin { 203151251b5Slogin return false; 204151251b5Slogin } 205151251b5Slogin } 2061496ba7bSLoGin let to_wakeup = guard.wait_list.pop_front().unwrap(); 207*0d6cf65aSLoGin drop(guard); 2081496ba7bSLoGin let res = ProcessManager::wakeup(&to_wakeup).is_ok(); 2091496ba7bSLoGin return res; 2101496ba7bSLoGin } 211151251b5Slogin 212cde5492fSlogin /// @brief 唤醒在队列中,符合条件的所有进程。 213cde5492fSlogin /// 2141496ba7bSLoGin /// @param state 用于判断的state,如果一个进程与这个state相同,或者为None(表示不进行这个判断),则唤醒这个进程。 2151496ba7bSLoGin pub fn wakeup_all(&self, state: Option<ProcessState>) { 216cde5492fSlogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock_irqsave(); 217cde5492fSlogin // 如果队列为空,则返回 218cde5492fSlogin if guard.wait_list.is_empty() { 219cde5492fSlogin return; 220cde5492fSlogin } 221cde5492fSlogin 2221496ba7bSLoGin let mut to_push_back: Vec<Arc<ProcessControlBlock>> = Vec::new(); 223cde5492fSlogin // 如果队列头部的pcb的state与给定的state相与,结果不为0,则唤醒 224cde5492fSlogin while let Some(to_wakeup) = guard.wait_list.pop_front() { 225a03c4f9dSLoGin let mut wake = false; 2261496ba7bSLoGin if let Some(state) = state { 227*0d6cf65aSLoGin if to_wakeup.sched_info().inner_lock_read_irqsave().state() == state { 228a03c4f9dSLoGin wake = true; 229a03c4f9dSLoGin } 230a03c4f9dSLoGin } else { 231a03c4f9dSLoGin wake = true; 232a03c4f9dSLoGin } 233a03c4f9dSLoGin 234a03c4f9dSLoGin if wake { 2351496ba7bSLoGin ProcessManager::wakeup(&to_wakeup).unwrap_or_else(|e| { 2361496ba7bSLoGin kerror!("wakeup pid: {:?} error: {:?}", to_wakeup.pid(), e); 2371496ba7bSLoGin }); 2381496ba7bSLoGin continue; 239a03c4f9dSLoGin } else { 240cde5492fSlogin to_push_back.push(to_wakeup); 241cde5492fSlogin } 242a03c4f9dSLoGin } 243a03c4f9dSLoGin 244cde5492fSlogin for to_wakeup in to_push_back { 245cde5492fSlogin guard.wait_list.push_back(to_wakeup); 246cde5492fSlogin } 247cde5492fSlogin } 248cde5492fSlogin 249151251b5Slogin /// @brief 获得当前等待队列的大小 250151251b5Slogin pub fn len(&self) -> usize { 251151251b5Slogin return self.0.lock().wait_list.len(); 252151251b5Slogin } 253151251b5Slogin } 254151251b5Slogin 255151251b5Slogin impl InnerWaitQueue { 256151251b5Slogin pub const INIT: InnerWaitQueue = InnerWaitQueue { 257151251b5Slogin wait_list: LinkedList::new(), 258151251b5Slogin }; 259151251b5Slogin } 26040609970SGnoCiYeH 26140609970SGnoCiYeH fn before_sleep_check(max_preempt: usize) { 26240609970SGnoCiYeH let pcb = ProcessManager::current_pcb(); 26340609970SGnoCiYeH if unlikely(pcb.preempt_count() > max_preempt) { 26440609970SGnoCiYeH kwarn!( 26540609970SGnoCiYeH "Process {:?}: Try to sleep when preempt count is {}", 26640609970SGnoCiYeH pcb.pid(), 26740609970SGnoCiYeH pcb.preempt_count() 26840609970SGnoCiYeH ); 26940609970SGnoCiYeH } 27040609970SGnoCiYeH } 27140609970SGnoCiYeH 27240609970SGnoCiYeH /// 事件等待队列 27340609970SGnoCiYeH #[derive(Debug)] 27440609970SGnoCiYeH pub struct EventWaitQueue { 27540609970SGnoCiYeH wait_list: SpinLock<Vec<(u64, Arc<ProcessControlBlock>)>>, 27640609970SGnoCiYeH } 27740609970SGnoCiYeH 27840609970SGnoCiYeH impl EventWaitQueue { 27940609970SGnoCiYeH pub fn new() -> Self { 28040609970SGnoCiYeH Self { 28140609970SGnoCiYeH wait_list: SpinLock::new(Vec::new()), 28240609970SGnoCiYeH } 28340609970SGnoCiYeH } 28440609970SGnoCiYeH 28540609970SGnoCiYeH /// ## 让当前进程在该队列上等待感兴趣的事件 28640609970SGnoCiYeH /// 28740609970SGnoCiYeH /// ### 参数 28840609970SGnoCiYeH /// - events: 进程感兴趣的事件,events最好是为位表示,一位表示一个事件 28940609970SGnoCiYeH /// 29040609970SGnoCiYeH /// 注意,使用前应该注意有可能其他地方定义了冲突的事件,可能会导致未定义行为 29140609970SGnoCiYeH pub fn sleep(&self, events: u64) { 29240609970SGnoCiYeH before_sleep_check(0); 29340609970SGnoCiYeH let mut guard = self.wait_list.lock_irqsave(); 29440609970SGnoCiYeH ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 29540609970SGnoCiYeH panic!("sleep error: {:?}", e); 29640609970SGnoCiYeH }); 29740609970SGnoCiYeH guard.push((events, ProcessManager::current_pcb())); 29840609970SGnoCiYeH drop(guard); 29940609970SGnoCiYeH sched(); 30040609970SGnoCiYeH } 30140609970SGnoCiYeH 30240609970SGnoCiYeH pub unsafe fn sleep_without_schedule(&self, events: u64) { 30340609970SGnoCiYeH before_sleep_check(1); 30440609970SGnoCiYeH let mut guard = self.wait_list.lock_irqsave(); 30540609970SGnoCiYeH ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 30640609970SGnoCiYeH panic!("sleep error: {:?}", e); 30740609970SGnoCiYeH }); 30840609970SGnoCiYeH guard.push((events, ProcessManager::current_pcb())); 30940609970SGnoCiYeH drop(guard); 31040609970SGnoCiYeH } 31140609970SGnoCiYeH 31240609970SGnoCiYeH pub fn sleep_unlock_spinlock<T>(&self, events: u64, to_unlock: SpinLockGuard<T>) { 31340609970SGnoCiYeH before_sleep_check(1); 314*0d6cf65aSLoGin let mut guard = self.wait_list.lock_irqsave(); 31540609970SGnoCiYeH let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 31640609970SGnoCiYeH ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 31740609970SGnoCiYeH panic!("sleep error: {:?}", e); 31840609970SGnoCiYeH }); 31940609970SGnoCiYeH drop(irq_guard); 32040609970SGnoCiYeH guard.push((events, ProcessManager::current_pcb())); 32140609970SGnoCiYeH drop(to_unlock); 32240609970SGnoCiYeH drop(guard); 32340609970SGnoCiYeH sched(); 32440609970SGnoCiYeH } 32540609970SGnoCiYeH 32640609970SGnoCiYeH /// ### 唤醒该队列上等待events的进程 32740609970SGnoCiYeH /// 32840609970SGnoCiYeH /// ### 参数 32940609970SGnoCiYeH /// - events: 发生的事件 33040609970SGnoCiYeH /// 33140609970SGnoCiYeH /// 需要注意的是,只要触发了events中的任意一件事件,进程都会被唤醒 33240609970SGnoCiYeH pub fn wakeup_any(&self, events: u64) -> usize { 33340609970SGnoCiYeH let mut ret = 0; 334*0d6cf65aSLoGin 335*0d6cf65aSLoGin let mut wq_guard = self.wait_list.lock_irqsave(); 336*0d6cf65aSLoGin wq_guard.retain(|(es, pcb)| { 33740609970SGnoCiYeH if *es & events > 0 { 33840609970SGnoCiYeH // 有感兴趣的事件 33940609970SGnoCiYeH if ProcessManager::wakeup(pcb).is_ok() { 34040609970SGnoCiYeH ret += 1; 34140609970SGnoCiYeH return true; 34240609970SGnoCiYeH } else { 34340609970SGnoCiYeH return false; 34440609970SGnoCiYeH } 34540609970SGnoCiYeH } else { 34640609970SGnoCiYeH return false; 34740609970SGnoCiYeH } 34840609970SGnoCiYeH }); 34940609970SGnoCiYeH ret 35040609970SGnoCiYeH } 35140609970SGnoCiYeH 35240609970SGnoCiYeH /// ### 唤醒该队列上等待events的进程 35340609970SGnoCiYeH /// 35440609970SGnoCiYeH /// ### 参数 35540609970SGnoCiYeH /// - events: 发生的事件 35640609970SGnoCiYeH /// 35740609970SGnoCiYeH /// 需要注意的是,只有满足所有事件的进程才会被唤醒 35840609970SGnoCiYeH pub fn wakeup(&self, events: u64) -> usize { 35940609970SGnoCiYeH let mut ret = 0; 360*0d6cf65aSLoGin let mut wq_guard = self.wait_list.lock_irqsave(); 361*0d6cf65aSLoGin wq_guard.retain(|(es, pcb)| { 36240609970SGnoCiYeH if *es == events { 36340609970SGnoCiYeH // 有感兴趣的事件 36440609970SGnoCiYeH if ProcessManager::wakeup(pcb).is_ok() { 36540609970SGnoCiYeH ret += 1; 36640609970SGnoCiYeH return true; 36740609970SGnoCiYeH } else { 36840609970SGnoCiYeH return false; 36940609970SGnoCiYeH } 37040609970SGnoCiYeH } else { 37140609970SGnoCiYeH return false; 37240609970SGnoCiYeH } 37340609970SGnoCiYeH }); 37440609970SGnoCiYeH ret 37540609970SGnoCiYeH } 37640609970SGnoCiYeH 37740609970SGnoCiYeH pub fn wakeup_all(&self) { 37840609970SGnoCiYeH self.wakeup_any(u64::MAX); 37940609970SGnoCiYeH } 38040609970SGnoCiYeH } 381