xref: /DragonOS/kernel/src/libs/wait_queue.rs (revision 151251b50b7ed55596edd32ffec49a4041010e2a)
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