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) { 33*40609970SGnoCiYeH 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 { 48*40609970SGnoCiYeH 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) { 77*40609970SGnoCiYeH 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) { 89*40609970SGnoCiYeH 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) { 101*40609970SGnoCiYeH 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>) { 116*40609970SGnoCiYeH 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>) { 132*40609970SGnoCiYeH 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>) { 148*40609970SGnoCiYeH 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>) { 164*40609970SGnoCiYeH 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 { 187151251b5Slogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 188151251b5Slogin // 如果队列为空,则返回 189151251b5Slogin if guard.wait_list.is_empty() { 190151251b5Slogin return false; 191151251b5Slogin } 192151251b5Slogin // 如果队列头部的pcb的state与给定的state相与,结果不为0,则唤醒 1931496ba7bSLoGin if let Some(state) = state { 1941496ba7bSLoGin if guard.wait_list.front().unwrap().sched_info().state() != state { 195151251b5Slogin return false; 196151251b5Slogin } 197151251b5Slogin } 1981496ba7bSLoGin let to_wakeup = guard.wait_list.pop_front().unwrap(); 1991496ba7bSLoGin let res = ProcessManager::wakeup(&to_wakeup).is_ok(); 2001496ba7bSLoGin return res; 2011496ba7bSLoGin } 202151251b5Slogin 203cde5492fSlogin /// @brief 唤醒在队列中,符合条件的所有进程。 204cde5492fSlogin /// 2051496ba7bSLoGin /// @param state 用于判断的state,如果一个进程与这个state相同,或者为None(表示不进行这个判断),则唤醒这个进程。 2061496ba7bSLoGin pub fn wakeup_all(&self, state: Option<ProcessState>) { 207cde5492fSlogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock_irqsave(); 208cde5492fSlogin // 如果队列为空,则返回 209cde5492fSlogin if guard.wait_list.is_empty() { 210cde5492fSlogin return; 211cde5492fSlogin } 212cde5492fSlogin 2131496ba7bSLoGin let mut to_push_back: Vec<Arc<ProcessControlBlock>> = Vec::new(); 214cde5492fSlogin // 如果队列头部的pcb的state与给定的state相与,结果不为0,则唤醒 215cde5492fSlogin while let Some(to_wakeup) = guard.wait_list.pop_front() { 216a03c4f9dSLoGin let mut wake = false; 2171496ba7bSLoGin if let Some(state) = state { 2181496ba7bSLoGin if to_wakeup.sched_info().state() == state { 219a03c4f9dSLoGin wake = true; 220a03c4f9dSLoGin } 221a03c4f9dSLoGin } else { 222a03c4f9dSLoGin wake = true; 223a03c4f9dSLoGin } 224a03c4f9dSLoGin 225a03c4f9dSLoGin if wake { 2261496ba7bSLoGin ProcessManager::wakeup(&to_wakeup).unwrap_or_else(|e| { 2271496ba7bSLoGin kerror!("wakeup pid: {:?} error: {:?}", to_wakeup.pid(), e); 2281496ba7bSLoGin }); 2291496ba7bSLoGin continue; 230a03c4f9dSLoGin } else { 231cde5492fSlogin to_push_back.push(to_wakeup); 232cde5492fSlogin } 233a03c4f9dSLoGin } 234a03c4f9dSLoGin 235cde5492fSlogin for to_wakeup in to_push_back { 236cde5492fSlogin guard.wait_list.push_back(to_wakeup); 237cde5492fSlogin } 238cde5492fSlogin } 239cde5492fSlogin 240151251b5Slogin /// @brief 获得当前等待队列的大小 241151251b5Slogin pub fn len(&self) -> usize { 242151251b5Slogin return self.0.lock().wait_list.len(); 243151251b5Slogin } 244151251b5Slogin } 245151251b5Slogin 246151251b5Slogin impl InnerWaitQueue { 247151251b5Slogin pub const INIT: InnerWaitQueue = InnerWaitQueue { 248151251b5Slogin wait_list: LinkedList::new(), 249151251b5Slogin }; 250151251b5Slogin } 251*40609970SGnoCiYeH 252*40609970SGnoCiYeH fn before_sleep_check(max_preempt: usize) { 253*40609970SGnoCiYeH let pcb = ProcessManager::current_pcb(); 254*40609970SGnoCiYeH if unlikely(pcb.preempt_count() > max_preempt) { 255*40609970SGnoCiYeH kwarn!( 256*40609970SGnoCiYeH "Process {:?}: Try to sleep when preempt count is {}", 257*40609970SGnoCiYeH pcb.pid(), 258*40609970SGnoCiYeH pcb.preempt_count() 259*40609970SGnoCiYeH ); 260*40609970SGnoCiYeH } 261*40609970SGnoCiYeH } 262*40609970SGnoCiYeH 263*40609970SGnoCiYeH /// 事件等待队列 264*40609970SGnoCiYeH #[derive(Debug)] 265*40609970SGnoCiYeH pub struct EventWaitQueue { 266*40609970SGnoCiYeH wait_list: SpinLock<Vec<(u64, Arc<ProcessControlBlock>)>>, 267*40609970SGnoCiYeH } 268*40609970SGnoCiYeH 269*40609970SGnoCiYeH impl EventWaitQueue { 270*40609970SGnoCiYeH pub fn new() -> Self { 271*40609970SGnoCiYeH Self { 272*40609970SGnoCiYeH wait_list: SpinLock::new(Vec::new()), 273*40609970SGnoCiYeH } 274*40609970SGnoCiYeH } 275*40609970SGnoCiYeH 276*40609970SGnoCiYeH /// ## 让当前进程在该队列上等待感兴趣的事件 277*40609970SGnoCiYeH /// 278*40609970SGnoCiYeH /// ### 参数 279*40609970SGnoCiYeH /// - events: 进程感兴趣的事件,events最好是为位表示,一位表示一个事件 280*40609970SGnoCiYeH /// 281*40609970SGnoCiYeH /// 注意,使用前应该注意有可能其他地方定义了冲突的事件,可能会导致未定义行为 282*40609970SGnoCiYeH pub fn sleep(&self, events: u64) { 283*40609970SGnoCiYeH before_sleep_check(0); 284*40609970SGnoCiYeH let mut guard = self.wait_list.lock_irqsave(); 285*40609970SGnoCiYeH ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 286*40609970SGnoCiYeH panic!("sleep error: {:?}", e); 287*40609970SGnoCiYeH }); 288*40609970SGnoCiYeH guard.push((events, ProcessManager::current_pcb())); 289*40609970SGnoCiYeH drop(guard); 290*40609970SGnoCiYeH sched(); 291*40609970SGnoCiYeH } 292*40609970SGnoCiYeH 293*40609970SGnoCiYeH pub unsafe fn sleep_without_schedule(&self, events: u64) { 294*40609970SGnoCiYeH before_sleep_check(1); 295*40609970SGnoCiYeH let mut guard = self.wait_list.lock_irqsave(); 296*40609970SGnoCiYeH ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 297*40609970SGnoCiYeH panic!("sleep error: {:?}", e); 298*40609970SGnoCiYeH }); 299*40609970SGnoCiYeH guard.push((events, ProcessManager::current_pcb())); 300*40609970SGnoCiYeH drop(guard); 301*40609970SGnoCiYeH } 302*40609970SGnoCiYeH 303*40609970SGnoCiYeH pub fn sleep_unlock_spinlock<T>(&self, events: u64, to_unlock: SpinLockGuard<T>) { 304*40609970SGnoCiYeH before_sleep_check(1); 305*40609970SGnoCiYeH let mut guard = self.wait_list.lock(); 306*40609970SGnoCiYeH let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 307*40609970SGnoCiYeH ProcessManager::mark_sleep(true).unwrap_or_else(|e| { 308*40609970SGnoCiYeH panic!("sleep error: {:?}", e); 309*40609970SGnoCiYeH }); 310*40609970SGnoCiYeH drop(irq_guard); 311*40609970SGnoCiYeH guard.push((events, ProcessManager::current_pcb())); 312*40609970SGnoCiYeH drop(to_unlock); 313*40609970SGnoCiYeH drop(guard); 314*40609970SGnoCiYeH sched(); 315*40609970SGnoCiYeH } 316*40609970SGnoCiYeH 317*40609970SGnoCiYeH /// ### 唤醒该队列上等待events的进程 318*40609970SGnoCiYeH /// 319*40609970SGnoCiYeH /// ### 参数 320*40609970SGnoCiYeH /// - events: 发生的事件 321*40609970SGnoCiYeH /// 322*40609970SGnoCiYeH /// 需要注意的是,只要触发了events中的任意一件事件,进程都会被唤醒 323*40609970SGnoCiYeH pub fn wakeup_any(&self, events: u64) -> usize { 324*40609970SGnoCiYeH let mut ret = 0; 325*40609970SGnoCiYeH let _ = self.wait_list.lock().extract_if(|(es, pcb)| { 326*40609970SGnoCiYeH if *es & events > 0 { 327*40609970SGnoCiYeH // 有感兴趣的事件 328*40609970SGnoCiYeH if ProcessManager::wakeup(pcb).is_ok() { 329*40609970SGnoCiYeH ret += 1; 330*40609970SGnoCiYeH return true; 331*40609970SGnoCiYeH } else { 332*40609970SGnoCiYeH return false; 333*40609970SGnoCiYeH } 334*40609970SGnoCiYeH } else { 335*40609970SGnoCiYeH return false; 336*40609970SGnoCiYeH } 337*40609970SGnoCiYeH }); 338*40609970SGnoCiYeH ret 339*40609970SGnoCiYeH } 340*40609970SGnoCiYeH 341*40609970SGnoCiYeH /// ### 唤醒该队列上等待events的进程 342*40609970SGnoCiYeH /// 343*40609970SGnoCiYeH /// ### 参数 344*40609970SGnoCiYeH /// - events: 发生的事件 345*40609970SGnoCiYeH /// 346*40609970SGnoCiYeH /// 需要注意的是,只有满足所有事件的进程才会被唤醒 347*40609970SGnoCiYeH pub fn wakeup(&self, events: u64) -> usize { 348*40609970SGnoCiYeH let mut ret = 0; 349*40609970SGnoCiYeH let _ = self.wait_list.lock().extract_if(|(es, pcb)| { 350*40609970SGnoCiYeH if *es == events { 351*40609970SGnoCiYeH // 有感兴趣的事件 352*40609970SGnoCiYeH if ProcessManager::wakeup(pcb).is_ok() { 353*40609970SGnoCiYeH ret += 1; 354*40609970SGnoCiYeH return true; 355*40609970SGnoCiYeH } else { 356*40609970SGnoCiYeH return false; 357*40609970SGnoCiYeH } 358*40609970SGnoCiYeH } else { 359*40609970SGnoCiYeH return false; 360*40609970SGnoCiYeH } 361*40609970SGnoCiYeH }); 362*40609970SGnoCiYeH ret 363*40609970SGnoCiYeH } 364*40609970SGnoCiYeH 365*40609970SGnoCiYeH pub fn wakeup_all(&self) { 366*40609970SGnoCiYeH self.wakeup_any(u64::MAX); 367*40609970SGnoCiYeH } 368*40609970SGnoCiYeH } 369