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