1*151251b5Slogin #![allow(dead_code)] 2*151251b5Slogin use alloc::collections::LinkedList; 3c8025a88Slogin 4*151251b5Slogin use crate::{ 5*151251b5Slogin arch::{asm::current::current_pcb, sched::sched}, 6*151251b5Slogin include::bindings::bindings::{ 7*151251b5Slogin process_control_block, process_wakeup, wait_queue_head_t, PROC_INTERRUPTIBLE, 8*151251b5Slogin PROC_UNINTERRUPTIBLE, 9*151251b5Slogin }, 10*151251b5Slogin }; 11*151251b5Slogin 12*151251b5Slogin use super::{ 13*151251b5Slogin list::list_init, 14*151251b5Slogin mutex::MutexGuard, 15*151251b5Slogin spinlock::{SpinLock, SpinLockGuard}, 16*151251b5Slogin }; 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 } 28*151251b5Slogin 29*151251b5Slogin #[derive(Debug)] 30*151251b5Slogin struct InnerWaitQueue { 31*151251b5Slogin /// 等待队列的链表 32*151251b5Slogin wait_list: LinkedList<&'static mut process_control_block>, 33*151251b5Slogin } 34*151251b5Slogin 35*151251b5Slogin /// 被自旋锁保护的等待队列 36*151251b5Slogin #[derive(Debug)] 37*151251b5Slogin pub struct WaitQueue(SpinLock<InnerWaitQueue>); 38*151251b5Slogin 39*151251b5Slogin impl WaitQueue { 40*151251b5Slogin pub const INIT: WaitQueue = WaitQueue(SpinLock::new(InnerWaitQueue::INIT)); 41*151251b5Slogin 42*151251b5Slogin /// @brief 让当前进程在等待队列上进行等待,并且,允许被信号打断 43*151251b5Slogin pub fn sleep(&self) { 44*151251b5Slogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 45*151251b5Slogin current_pcb().state = PROC_INTERRUPTIBLE as u64; 46*151251b5Slogin guard.wait_list.push_back(current_pcb()); 47*151251b5Slogin drop(guard); 48*151251b5Slogin sched(); 49*151251b5Slogin } 50*151251b5Slogin 51*151251b5Slogin /// @brief 让当前进程在等待队列上进行等待,并且,不允许被信号打断 52*151251b5Slogin pub fn sleep_uninterruptible(&self) { 53*151251b5Slogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 54*151251b5Slogin current_pcb().state = PROC_UNINTERRUPTIBLE as u64; 55*151251b5Slogin guard.wait_list.push_back(current_pcb()); 56*151251b5Slogin drop(guard); 57*151251b5Slogin sched(); 58*151251b5Slogin } 59*151251b5Slogin 60*151251b5Slogin /// @brief 让当前进程在等待队列上进行等待,并且,允许被信号打断。 61*151251b5Slogin /// 在当前进程的pcb加入队列后,解锁指定的自旋锁。 62*151251b5Slogin pub fn sleep_unlock_spinlock<T>(&self, to_unlock: SpinLockGuard<T>) { 63*151251b5Slogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 64*151251b5Slogin current_pcb().state = PROC_INTERRUPTIBLE as u64; 65*151251b5Slogin guard.wait_list.push_back(current_pcb()); 66*151251b5Slogin drop(to_unlock); 67*151251b5Slogin drop(guard); 68*151251b5Slogin sched(); 69*151251b5Slogin } 70*151251b5Slogin 71*151251b5Slogin /// @brief 让当前进程在等待队列上进行等待,并且,允许被信号打断。 72*151251b5Slogin /// 在当前进程的pcb加入队列后,解锁指定的Mutex。 73*151251b5Slogin pub fn sleep_unlock_mutex<T>(&self, to_unlock: MutexGuard<T>) { 74*151251b5Slogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 75*151251b5Slogin current_pcb().state = PROC_INTERRUPTIBLE as u64; 76*151251b5Slogin guard.wait_list.push_back(current_pcb()); 77*151251b5Slogin drop(to_unlock); 78*151251b5Slogin drop(guard); 79*151251b5Slogin sched(); 80*151251b5Slogin } 81*151251b5Slogin 82*151251b5Slogin /// @brief 让当前进程在等待队列上进行等待,并且,不允许被信号打断。 83*151251b5Slogin /// 在当前进程的pcb加入队列后,解锁指定的自旋锁。 84*151251b5Slogin pub fn sleep_uninterruptible_unlock_spinlock<T>(&self, to_unlock: SpinLockGuard<T>) { 85*151251b5Slogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 86*151251b5Slogin current_pcb().state = PROC_UNINTERRUPTIBLE as u64; 87*151251b5Slogin guard.wait_list.push_back(current_pcb()); 88*151251b5Slogin drop(to_unlock); 89*151251b5Slogin drop(guard); 90*151251b5Slogin sched(); 91*151251b5Slogin } 92*151251b5Slogin 93*151251b5Slogin /// @brief 让当前进程在等待队列上进行等待,并且,不允许被信号打断。 94*151251b5Slogin /// 在当前进程的pcb加入队列后,解锁指定的Mutex。 95*151251b5Slogin pub fn sleep_uninterruptible_unlock_mutex<T>(&self, to_unlock: MutexGuard<T>) { 96*151251b5Slogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 97*151251b5Slogin current_pcb().state = PROC_UNINTERRUPTIBLE as u64; 98*151251b5Slogin guard.wait_list.push_back(current_pcb()); 99*151251b5Slogin drop(to_unlock); 100*151251b5Slogin drop(guard); 101*151251b5Slogin sched(); 102*151251b5Slogin } 103*151251b5Slogin 104*151251b5Slogin /// @brief 唤醒在队列中等待的第一个进程。 105*151251b5Slogin /// 如果这个进程的state与给定的state进行and操作之后,结果不为0,则唤醒它。 106*151251b5Slogin /// 107*151251b5Slogin /// @param state 用于判断的state,如果队列中第一个进程的state与它进行and操作之后,结果不为0,则唤醒这个进程。 108*151251b5Slogin /// 109*151251b5Slogin /// @return true 成功唤醒进程 110*151251b5Slogin /// @return false 没有唤醒进程 111*151251b5Slogin pub fn wakeup(&self, state: u64) -> bool { 112*151251b5Slogin let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock(); 113*151251b5Slogin // 如果队列为空,则返回 114*151251b5Slogin if guard.wait_list.is_empty() { 115*151251b5Slogin return false; 116*151251b5Slogin } 117*151251b5Slogin 118*151251b5Slogin // 如果队列头部的pcb的state与给定的state相与,结果不为0,则唤醒 119*151251b5Slogin if (guard.wait_list.front().unwrap().state & state) != 0 { 120*151251b5Slogin let to_wakeup = guard.wait_list.pop_front().unwrap(); 121*151251b5Slogin unsafe { 122*151251b5Slogin process_wakeup(to_wakeup); 123*151251b5Slogin } 124*151251b5Slogin return true; 125*151251b5Slogin } else { 126*151251b5Slogin return false; 127*151251b5Slogin } 128*151251b5Slogin } 129*151251b5Slogin 130*151251b5Slogin /// @brief 获得当前等待队列的大小 131*151251b5Slogin pub fn len(&self)->usize{ 132*151251b5Slogin return self.0.lock().wait_list.len(); 133*151251b5Slogin } 134*151251b5Slogin } 135*151251b5Slogin 136*151251b5Slogin impl InnerWaitQueue { 137*151251b5Slogin pub const INIT: InnerWaitQueue = InnerWaitQueue { 138*151251b5Slogin wait_list: LinkedList::new(), 139*151251b5Slogin }; 140*151251b5Slogin } 141