1151251b5Slogin #![allow(dead_code)] 2*cde5492fSlogin use alloc::{collections::LinkedList, vec::Vec}; 3c8025a88Slogin 4151251b5Slogin use crate::{ 5151251b5Slogin arch::{asm::current::current_pcb, sched::sched}, 6151251b5Slogin include::bindings::bindings::{ 7151251b5Slogin process_control_block, process_wakeup, wait_queue_head_t, PROC_INTERRUPTIBLE, 8151251b5Slogin PROC_UNINTERRUPTIBLE, 9151251b5Slogin }, 10151251b5Slogin }; 11151251b5Slogin 12151251b5Slogin use super::{ 13151251b5Slogin list::list_init, 14151251b5Slogin mutex::MutexGuard, 15151251b5Slogin spinlock::{SpinLock, SpinLockGuard}, 16151251b5Slogin }; 17c8025a88Slogin 18c8025a88Slogin impl Default for wait_queue_head_t { 19c8025a88Slogin fn default() -> Self { 2006b09f34Skong let mut x = Self { 2106b09f34Skong wait_list: Default::default(), 2206b09f34Skong lock: Default::default(), 2306b09f34Skong }; 24c8025a88Slogin list_init(&mut x.wait_list); 25c8025a88Slogin return x; 26c8025a88Slogin } 27c8025a88Slogin } 28151251b5Slogin 29151251b5Slogin #[derive(Debug)] 30151251b5Slogin struct InnerWaitQueue { 31151251b5Slogin /// 等待队列的链表 32151251b5Slogin wait_list: LinkedList<&'static mut process_control_block>, 33151251b5Slogin } 34151251b5Slogin 35151251b5Slogin /// 被自旋锁保护的等待队列 36151251b5Slogin #[derive(Debug)] 37151251b5Slogin pub struct WaitQueue(SpinLock<InnerWaitQueue>); 38151251b5Slogin 39151251b5Slogin impl WaitQueue { 40151251b5Slogin pub const INIT: WaitQueue = WaitQueue(SpinLock::new(InnerWaitQueue::INIT)); 41151251b5Slogin 42151251b5Slogin /// @brief 让当前进程在等待队列上进行等待,并且,允许被信号打断 43151251b5Slogin pub fn sleep(&self) { 44151251b5Slogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 45151251b5Slogin current_pcb().state = PROC_INTERRUPTIBLE as u64; 46151251b5Slogin guard.wait_list.push_back(current_pcb()); 47151251b5Slogin drop(guard); 48151251b5Slogin sched(); 49151251b5Slogin } 50151251b5Slogin 51151251b5Slogin /// @brief 让当前进程在等待队列上进行等待,并且,不允许被信号打断 52151251b5Slogin pub fn sleep_uninterruptible(&self) { 53151251b5Slogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 54151251b5Slogin current_pcb().state = PROC_UNINTERRUPTIBLE as u64; 55151251b5Slogin guard.wait_list.push_back(current_pcb()); 56151251b5Slogin drop(guard); 57151251b5Slogin sched(); 58151251b5Slogin } 59151251b5Slogin 60151251b5Slogin /// @brief 让当前进程在等待队列上进行等待,并且,允许被信号打断。 61151251b5Slogin /// 在当前进程的pcb加入队列后,解锁指定的自旋锁。 62151251b5Slogin pub fn sleep_unlock_spinlock<T>(&self, to_unlock: SpinLockGuard<T>) { 63151251b5Slogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 64151251b5Slogin current_pcb().state = PROC_INTERRUPTIBLE as u64; 65151251b5Slogin guard.wait_list.push_back(current_pcb()); 66151251b5Slogin drop(to_unlock); 67151251b5Slogin drop(guard); 68151251b5Slogin sched(); 69151251b5Slogin } 70151251b5Slogin 71151251b5Slogin /// @brief 让当前进程在等待队列上进行等待,并且,允许被信号打断。 72151251b5Slogin /// 在当前进程的pcb加入队列后,解锁指定的Mutex。 73151251b5Slogin pub fn sleep_unlock_mutex<T>(&self, to_unlock: MutexGuard<T>) { 74151251b5Slogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 75151251b5Slogin current_pcb().state = PROC_INTERRUPTIBLE as u64; 76151251b5Slogin guard.wait_list.push_back(current_pcb()); 77151251b5Slogin drop(to_unlock); 78151251b5Slogin drop(guard); 79151251b5Slogin sched(); 80151251b5Slogin } 81151251b5Slogin 82151251b5Slogin /// @brief 让当前进程在等待队列上进行等待,并且,不允许被信号打断。 83151251b5Slogin /// 在当前进程的pcb加入队列后,解锁指定的自旋锁。 84151251b5Slogin pub fn sleep_uninterruptible_unlock_spinlock<T>(&self, to_unlock: SpinLockGuard<T>) { 85151251b5Slogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 86151251b5Slogin current_pcb().state = PROC_UNINTERRUPTIBLE as u64; 87151251b5Slogin guard.wait_list.push_back(current_pcb()); 88151251b5Slogin drop(to_unlock); 89151251b5Slogin drop(guard); 90151251b5Slogin sched(); 91151251b5Slogin } 92151251b5Slogin 93151251b5Slogin /// @brief 让当前进程在等待队列上进行等待,并且,不允许被信号打断。 94151251b5Slogin /// 在当前进程的pcb加入队列后,解锁指定的Mutex。 95151251b5Slogin pub fn sleep_uninterruptible_unlock_mutex<T>(&self, to_unlock: MutexGuard<T>) { 96151251b5Slogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 97151251b5Slogin current_pcb().state = PROC_UNINTERRUPTIBLE as u64; 98151251b5Slogin guard.wait_list.push_back(current_pcb()); 99151251b5Slogin drop(to_unlock); 100151251b5Slogin drop(guard); 101151251b5Slogin sched(); 102151251b5Slogin } 103151251b5Slogin 104151251b5Slogin /// @brief 唤醒在队列中等待的第一个进程。 105151251b5Slogin /// 如果这个进程的state与给定的state进行and操作之后,结果不为0,则唤醒它。 106151251b5Slogin /// 107151251b5Slogin /// @param state 用于判断的state,如果队列中第一个进程的state与它进行and操作之后,结果不为0,则唤醒这个进程。 108151251b5Slogin /// 109151251b5Slogin /// @return true 成功唤醒进程 110151251b5Slogin /// @return false 没有唤醒进程 111151251b5Slogin pub fn wakeup(&self, state: u64) -> bool { 112151251b5Slogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 113151251b5Slogin // 如果队列为空,则返回 114151251b5Slogin if guard.wait_list.is_empty() { 115151251b5Slogin return false; 116151251b5Slogin } 117151251b5Slogin 118151251b5Slogin // 如果队列头部的pcb的state与给定的state相与,结果不为0,则唤醒 119151251b5Slogin if (guard.wait_list.front().unwrap().state & state) != 0 { 120151251b5Slogin let to_wakeup = guard.wait_list.pop_front().unwrap(); 121151251b5Slogin unsafe { 122151251b5Slogin process_wakeup(to_wakeup); 123151251b5Slogin } 124151251b5Slogin return true; 125151251b5Slogin } else { 126151251b5Slogin return false; 127151251b5Slogin } 128151251b5Slogin } 129151251b5Slogin 130*cde5492fSlogin /// @brief 唤醒在队列中,符合条件的所有进程。 131*cde5492fSlogin /// 132*cde5492fSlogin /// @param state 用于判断的state,如果队列中第一个进程的state与它进行and操作之后,结果不为0,则唤醒这个进程。 133*cde5492fSlogin pub fn wakeup_all(&self, state: u64) { 134*cde5492fSlogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock_irqsave(); 135*cde5492fSlogin // 如果队列为空,则返回 136*cde5492fSlogin if guard.wait_list.is_empty() { 137*cde5492fSlogin return; 138*cde5492fSlogin } 139*cde5492fSlogin 140*cde5492fSlogin let mut to_push_back: Vec<&mut process_control_block> = Vec::new(); 141*cde5492fSlogin // 如果队列头部的pcb的state与给定的state相与,结果不为0,则唤醒 142*cde5492fSlogin while let Some(to_wakeup) = guard.wait_list.pop_front() { 143*cde5492fSlogin if (to_wakeup.state & state) != 0 { 144*cde5492fSlogin unsafe { 145*cde5492fSlogin process_wakeup(to_wakeup); 146*cde5492fSlogin } 147*cde5492fSlogin } else { 148*cde5492fSlogin to_push_back.push(to_wakeup); 149*cde5492fSlogin } 150*cde5492fSlogin } 151*cde5492fSlogin 152*cde5492fSlogin for to_wakeup in to_push_back { 153*cde5492fSlogin guard.wait_list.push_back(to_wakeup); 154*cde5492fSlogin } 155*cde5492fSlogin } 156*cde5492fSlogin 157151251b5Slogin /// @brief 获得当前等待队列的大小 158151251b5Slogin pub fn len(&self) -> usize { 159151251b5Slogin return self.0.lock().wait_list.len(); 160151251b5Slogin } 161151251b5Slogin } 162151251b5Slogin 163151251b5Slogin impl InnerWaitQueue { 164151251b5Slogin pub const INIT: InnerWaitQueue = InnerWaitQueue { 165151251b5Slogin wait_list: LinkedList::new(), 166151251b5Slogin }; 167151251b5Slogin } 168