xref: /DragonOS/kernel/src/libs/wait_queue.rs (revision dc9b4fea1bcff86cfb49293552654e2dd038ae9e)
1e2841179SLoGin // #![allow(dead_code)]
22f6f547aSGnoCiYeH use core::intrinsics::unlikely;
32f6f547aSGnoCiYeH 
41496ba7bSLoGin use alloc::{collections::LinkedList, sync::Arc, vec::Vec};
52eab6dd7S曾俊 use log::{error, warn};
6*dc9b4feaSLoGin use system_error::SystemError;
7c8025a88Slogin 
8151251b5Slogin use crate::{
9*dc9b4feaSLoGin     arch::{ipc::signal::Signal, CurrentIrqArch},
10f678331aShanjiezhou     exception::InterruptArch,
111496ba7bSLoGin     process::{ProcessControlBlock, ProcessManager, ProcessState},
12f0c87a89SGnoCiYeH     sched::{schedule, SchedMode},
13151251b5Slogin };
14151251b5Slogin 
15151251b5Slogin use super::{
16151251b5Slogin     mutex::MutexGuard,
17151251b5Slogin     spinlock::{SpinLock, SpinLockGuard},
18151251b5Slogin };
19c8025a88Slogin 
20151251b5Slogin #[derive(Debug)]
21151251b5Slogin struct InnerWaitQueue {
22151251b5Slogin     /// 等待队列的链表
231496ba7bSLoGin     wait_list: LinkedList<Arc<ProcessControlBlock>>,
24151251b5Slogin }
25151251b5Slogin 
26151251b5Slogin /// 被自旋锁保护的等待队列
27151251b5Slogin #[derive(Debug)]
28151251b5Slogin pub struct WaitQueue(SpinLock<InnerWaitQueue>);
29151251b5Slogin 
30e2841179SLoGin #[allow(dead_code)]
31151251b5Slogin impl WaitQueue {
default() -> Self32b5b571e0SLoGin     pub const fn default() -> Self {
33b5b571e0SLoGin         WaitQueue(SpinLock::new(InnerWaitQueue::INIT))
34b5b571e0SLoGin     }
35151251b5Slogin 
prepare_to_wait_event(&self, interruptible: bool) -> Result<(), SystemError>36*dc9b4feaSLoGin     pub fn prepare_to_wait_event(&self, interruptible: bool) -> Result<(), SystemError> {
37*dc9b4feaSLoGin         let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock_irqsave();
38*dc9b4feaSLoGin         let pcb = ProcessManager::current_pcb();
39*dc9b4feaSLoGin         if Signal::signal_pending_state(interruptible, false, &pcb) {
40*dc9b4feaSLoGin             return Err(SystemError::ERESTARTSYS);
41*dc9b4feaSLoGin         } else {
42*dc9b4feaSLoGin             ProcessManager::mark_sleep(interruptible).unwrap_or_else(|e| {
43*dc9b4feaSLoGin                 panic!("sleep error: {:?}", e);
44*dc9b4feaSLoGin             });
45*dc9b4feaSLoGin             guard.wait_list.push_back(ProcessManager::current_pcb());
46*dc9b4feaSLoGin             drop(guard);
47*dc9b4feaSLoGin         }
48*dc9b4feaSLoGin         Ok(())
49*dc9b4feaSLoGin     }
50*dc9b4feaSLoGin 
finish_wait(&self)51*dc9b4feaSLoGin     pub fn finish_wait(&self) {
52*dc9b4feaSLoGin         let pcb = ProcessManager::current_pcb();
53*dc9b4feaSLoGin         let mut writer = pcb.sched_info().inner_lock_write_irqsave();
54*dc9b4feaSLoGin         let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock_irqsave();
55*dc9b4feaSLoGin 
56*dc9b4feaSLoGin         writer.set_state(ProcessState::Runnable);
57*dc9b4feaSLoGin         writer.set_wakeup();
58*dc9b4feaSLoGin 
59*dc9b4feaSLoGin         guard.wait_list.retain(|x| !Arc::ptr_eq(x, &pcb));
60*dc9b4feaSLoGin         drop(guard);
61*dc9b4feaSLoGin         drop(writer);
62*dc9b4feaSLoGin     }
63*dc9b4feaSLoGin 
64151251b5Slogin     /// @brief 让当前进程在等待队列上进行等待,并且,允许被信号打断
sleep(&self)65151251b5Slogin     pub fn sleep(&self) {
6640609970SGnoCiYeH         before_sleep_check(0);
671496ba7bSLoGin         let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock_irqsave();
681496ba7bSLoGin         ProcessManager::mark_sleep(true).unwrap_or_else(|e| {
691496ba7bSLoGin             panic!("sleep error: {:?}", e);
701496ba7bSLoGin         });
711496ba7bSLoGin         guard.wait_list.push_back(ProcessManager::current_pcb());
72151251b5Slogin         drop(guard);
73f0c87a89SGnoCiYeH         schedule(SchedMode::SM_NONE);
74151251b5Slogin     }
75151251b5Slogin 
76f678331aShanjiezhou     /// @brief 让当前进程在等待队列上进行等待,并且,在释放waitqueue的锁之前,执行f函数闭包
sleep_with_func<F>(&self, f: F) where F: FnOnce(),77f678331aShanjiezhou     pub fn sleep_with_func<F>(&self, f: F)
78f678331aShanjiezhou     where
79f678331aShanjiezhou         F: FnOnce(),
80f678331aShanjiezhou     {
8140609970SGnoCiYeH         before_sleep_check(0);
82*dc9b4feaSLoGin         let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock_irqsave();
831496ba7bSLoGin         let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
841496ba7bSLoGin         ProcessManager::mark_sleep(true).unwrap_or_else(|e| {
851496ba7bSLoGin             panic!("sleep error: {:?}", e);
861496ba7bSLoGin         });
871496ba7bSLoGin         drop(irq_guard);
881496ba7bSLoGin         guard.wait_list.push_back(ProcessManager::current_pcb());
89f678331aShanjiezhou         f();
902f6f547aSGnoCiYeH 
91f678331aShanjiezhou         drop(guard);
92f0c87a89SGnoCiYeH         schedule(SchedMode::SM_NONE);
93f678331aShanjiezhou     }
94f678331aShanjiezhou 
95f678331aShanjiezhou     /// @brief 让当前进程在等待队列上进行等待. 但是,在释放waitqueue的锁之后,不会调用调度函数。
96f678331aShanjiezhou     /// 这样的设计,是为了让调用者可以在执行本函数之后,执行一些操作,然后再【手动调用调度函数】。
97f678331aShanjiezhou     ///
98f678331aShanjiezhou     /// 执行本函数前,需要确保处于【中断禁止】状态。
99f678331aShanjiezhou     ///
100f678331aShanjiezhou     /// 尽管sleep_with_func和sleep_without_schedule都可以实现这个功能,但是,sleep_with_func会在释放锁之前,执行f函数闭包。
101f678331aShanjiezhou     ///
102f678331aShanjiezhou     /// 考虑这样一个场景:
103f678331aShanjiezhou     /// 等待队列位于某个自旋锁保护的数据结构A中,我们希望在进程睡眠的同时,释放数据结构A的锁。
104f678331aShanjiezhou     /// 在这种情况下,如果使用sleep_with_func,所有权系统不会允许我们这么做。
105f678331aShanjiezhou     /// 因此,sleep_without_schedule的设计,正是为了解决这个问题。
106f678331aShanjiezhou     ///
107f678331aShanjiezhou     /// 由于sleep_without_schedule不会调用调度函数,因此,如果开发者忘记在执行本函数之后,手动调用调度函数,
108f678331aShanjiezhou     /// 由于时钟中断到来或者‘其他cpu kick了当前cpu’,可能会导致一些未定义的行为。
sleep_without_schedule(&self)109f678331aShanjiezhou     pub unsafe fn sleep_without_schedule(&self) {
11040609970SGnoCiYeH         before_sleep_check(1);
111f678331aShanjiezhou         // 安全检查:确保当前处于中断禁止状态
112b5b571e0SLoGin         assert!(!CurrentIrqArch::is_irq_enabled());
113f678331aShanjiezhou         let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
1141496ba7bSLoGin         ProcessManager::mark_sleep(true).unwrap_or_else(|e| {
1151496ba7bSLoGin             panic!("sleep error: {:?}", e);
1161496ba7bSLoGin         });
1171496ba7bSLoGin         guard.wait_list.push_back(ProcessManager::current_pcb());
1181496ba7bSLoGin         drop(guard);
1191496ba7bSLoGin     }
1201496ba7bSLoGin 
sleep_without_schedule_uninterruptible(&self)1211496ba7bSLoGin     pub unsafe fn sleep_without_schedule_uninterruptible(&self) {
1228cb2e9b3SLoGin         before_sleep_check(1);
1231496ba7bSLoGin         // 安全检查:确保当前处于中断禁止状态
124b5b571e0SLoGin         assert!(!CurrentIrqArch::is_irq_enabled());
1251496ba7bSLoGin         let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
1261496ba7bSLoGin         ProcessManager::mark_sleep(false).unwrap_or_else(|e| {
1271496ba7bSLoGin             panic!("sleep error: {:?}", e);
1281496ba7bSLoGin         });
1291496ba7bSLoGin         guard.wait_list.push_back(ProcessManager::current_pcb());
130f678331aShanjiezhou         drop(guard);
131f678331aShanjiezhou     }
132151251b5Slogin     /// @brief 让当前进程在等待队列上进行等待,并且,不允许被信号打断
sleep_uninterruptible(&self)133151251b5Slogin     pub fn sleep_uninterruptible(&self) {
13440609970SGnoCiYeH         before_sleep_check(0);
135151251b5Slogin         let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
1361496ba7bSLoGin         let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
1371496ba7bSLoGin         ProcessManager::mark_sleep(false).unwrap_or_else(|e| {
1381496ba7bSLoGin             panic!("sleep error: {:?}", e);
1391496ba7bSLoGin         });
1401496ba7bSLoGin         drop(irq_guard);
1411496ba7bSLoGin         guard.wait_list.push_back(ProcessManager::current_pcb());
142151251b5Slogin         drop(guard);
143f0c87a89SGnoCiYeH         schedule(SchedMode::SM_NONE);
144151251b5Slogin     }
145151251b5Slogin 
146151251b5Slogin     /// @brief 让当前进程在等待队列上进行等待,并且,允许被信号打断。
147151251b5Slogin     /// 在当前进程的pcb加入队列后,解锁指定的自旋锁。
sleep_unlock_spinlock<T>(&self, to_unlock: SpinLockGuard<T>)148151251b5Slogin     pub fn sleep_unlock_spinlock<T>(&self, to_unlock: SpinLockGuard<T>) {
14940609970SGnoCiYeH         before_sleep_check(1);
150151251b5Slogin         let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
1511496ba7bSLoGin         let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
1521496ba7bSLoGin         ProcessManager::mark_sleep(true).unwrap_or_else(|e| {
1531496ba7bSLoGin             panic!("sleep error: {:?}", e);
1541496ba7bSLoGin         });
1551496ba7bSLoGin         drop(irq_guard);
1561496ba7bSLoGin         guard.wait_list.push_back(ProcessManager::current_pcb());
157151251b5Slogin         drop(to_unlock);
158151251b5Slogin         drop(guard);
159f0c87a89SGnoCiYeH         schedule(SchedMode::SM_NONE);
160151251b5Slogin     }
161151251b5Slogin 
162151251b5Slogin     /// @brief 让当前进程在等待队列上进行等待,并且,允许被信号打断。
163151251b5Slogin     /// 在当前进程的pcb加入队列后,解锁指定的Mutex。
sleep_unlock_mutex<T>(&self, to_unlock: MutexGuard<T>)164151251b5Slogin     pub fn sleep_unlock_mutex<T>(&self, to_unlock: MutexGuard<T>) {
16540609970SGnoCiYeH         before_sleep_check(1);
166151251b5Slogin         let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
1671496ba7bSLoGin         let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
1681496ba7bSLoGin         ProcessManager::mark_sleep(true).unwrap_or_else(|e| {
1691496ba7bSLoGin             panic!("sleep error: {:?}", e);
1701496ba7bSLoGin         });
1711496ba7bSLoGin         drop(irq_guard);
1721496ba7bSLoGin         guard.wait_list.push_back(ProcessManager::current_pcb());
173151251b5Slogin         drop(to_unlock);
174151251b5Slogin         drop(guard);
175f0c87a89SGnoCiYeH         schedule(SchedMode::SM_NONE);
176151251b5Slogin     }
177151251b5Slogin 
178151251b5Slogin     /// @brief 让当前进程在等待队列上进行等待,并且,不允许被信号打断。
179151251b5Slogin     /// 在当前进程的pcb加入队列后,解锁指定的自旋锁。
sleep_uninterruptible_unlock_spinlock<T>(&self, to_unlock: SpinLockGuard<T>)180151251b5Slogin     pub fn sleep_uninterruptible_unlock_spinlock<T>(&self, to_unlock: SpinLockGuard<T>) {
18140609970SGnoCiYeH         before_sleep_check(1);
182151251b5Slogin         let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
1831496ba7bSLoGin         let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
1841496ba7bSLoGin         ProcessManager::mark_sleep(false).unwrap_or_else(|e| {
1851496ba7bSLoGin             panic!("sleep error: {:?}", e);
1861496ba7bSLoGin         });
1871496ba7bSLoGin         drop(irq_guard);
1881496ba7bSLoGin         guard.wait_list.push_back(ProcessManager::current_pcb());
189151251b5Slogin         drop(to_unlock);
190151251b5Slogin         drop(guard);
191f0c87a89SGnoCiYeH         schedule(SchedMode::SM_NONE);
192151251b5Slogin     }
193151251b5Slogin 
194151251b5Slogin     /// @brief 让当前进程在等待队列上进行等待,并且,不允许被信号打断。
195151251b5Slogin     /// 在当前进程的pcb加入队列后,解锁指定的Mutex。
sleep_uninterruptible_unlock_mutex<T>(&self, to_unlock: MutexGuard<T>)196151251b5Slogin     pub fn sleep_uninterruptible_unlock_mutex<T>(&self, to_unlock: MutexGuard<T>) {
19740609970SGnoCiYeH         before_sleep_check(1);
198151251b5Slogin         let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
1991496ba7bSLoGin         let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
2001496ba7bSLoGin         ProcessManager::mark_sleep(false).unwrap_or_else(|e| {
2011496ba7bSLoGin             panic!("sleep error: {:?}", e);
2021496ba7bSLoGin         });
2031496ba7bSLoGin         drop(irq_guard);
2041496ba7bSLoGin 
2051496ba7bSLoGin         guard.wait_list.push_back(ProcessManager::current_pcb());
2061496ba7bSLoGin 
207151251b5Slogin         drop(to_unlock);
208151251b5Slogin         drop(guard);
209f0c87a89SGnoCiYeH         schedule(SchedMode::SM_NONE);
210151251b5Slogin     }
211151251b5Slogin 
212151251b5Slogin     /// @brief 唤醒在队列中等待的第一个进程。
213151251b5Slogin     /// 如果这个进程的state与给定的state进行and操作之后,结果不为0,则唤醒它。
214151251b5Slogin     ///
2151496ba7bSLoGin     /// @param state 用于判断的state,如果队列第一个进程与这个state相同,或者为None(表示不进行这个判断),则唤醒这个进程。
216151251b5Slogin     ///
217151251b5Slogin     /// @return true 成功唤醒进程
218151251b5Slogin     /// @return false 没有唤醒进程
wakeup(&self, state: Option<ProcessState>) -> bool2191496ba7bSLoGin     pub fn wakeup(&self, state: Option<ProcessState>) -> bool {
2200d6cf65aSLoGin         let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock_irqsave();
221151251b5Slogin         // 如果队列为空,则返回
222151251b5Slogin         if guard.wait_list.is_empty() {
223151251b5Slogin             return false;
224151251b5Slogin         }
225151251b5Slogin         // 如果队列头部的pcb的state与给定的state相与,结果不为0,则唤醒
2261496ba7bSLoGin         if let Some(state) = state {
2270d6cf65aSLoGin             if guard
2280d6cf65aSLoGin                 .wait_list
2290d6cf65aSLoGin                 .front()
2300d6cf65aSLoGin                 .unwrap()
2310d6cf65aSLoGin                 .sched_info()
2320d6cf65aSLoGin                 .inner_lock_read_irqsave()
2330d6cf65aSLoGin                 .state()
2340d6cf65aSLoGin                 != state
2350d6cf65aSLoGin             {
236151251b5Slogin                 return false;
237151251b5Slogin             }
238151251b5Slogin         }
2391496ba7bSLoGin         let to_wakeup = guard.wait_list.pop_front().unwrap();
2400d6cf65aSLoGin         drop(guard);
2411496ba7bSLoGin         let res = ProcessManager::wakeup(&to_wakeup).is_ok();
2421496ba7bSLoGin         return res;
2431496ba7bSLoGin     }
244151251b5Slogin 
245cde5492fSlogin     /// @brief 唤醒在队列中,符合条件的所有进程。
246cde5492fSlogin     ///
2471496ba7bSLoGin     /// @param state 用于判断的state,如果一个进程与这个state相同,或者为None(表示不进行这个判断),则唤醒这个进程。
wakeup_all(&self, state: Option<ProcessState>)2481496ba7bSLoGin     pub fn wakeup_all(&self, state: Option<ProcessState>) {
249cde5492fSlogin         let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock_irqsave();
250cde5492fSlogin         // 如果队列为空,则返回
251cde5492fSlogin         if guard.wait_list.is_empty() {
252cde5492fSlogin             return;
253cde5492fSlogin         }
254cde5492fSlogin 
2551496ba7bSLoGin         let mut to_push_back: Vec<Arc<ProcessControlBlock>> = Vec::new();
256cde5492fSlogin         // 如果队列头部的pcb的state与给定的state相与,结果不为0,则唤醒
257cde5492fSlogin         while let Some(to_wakeup) = guard.wait_list.pop_front() {
258a03c4f9dSLoGin             let mut wake = false;
2591496ba7bSLoGin             if let Some(state) = state {
2600d6cf65aSLoGin                 if to_wakeup.sched_info().inner_lock_read_irqsave().state() == state {
261a03c4f9dSLoGin                     wake = true;
262a03c4f9dSLoGin                 }
263a03c4f9dSLoGin             } else {
264a03c4f9dSLoGin                 wake = true;
265a03c4f9dSLoGin             }
266a03c4f9dSLoGin 
267a03c4f9dSLoGin             if wake {
2681496ba7bSLoGin                 ProcessManager::wakeup(&to_wakeup).unwrap_or_else(|e| {
2692eab6dd7S曾俊                     error!("wakeup pid: {:?} error: {:?}", to_wakeup.pid(), e);
2701496ba7bSLoGin                 });
2711496ba7bSLoGin                 continue;
272a03c4f9dSLoGin             } else {
273cde5492fSlogin                 to_push_back.push(to_wakeup);
274cde5492fSlogin             }
275a03c4f9dSLoGin         }
276a03c4f9dSLoGin 
277cde5492fSlogin         for to_wakeup in to_push_back {
278cde5492fSlogin             guard.wait_list.push_back(to_wakeup);
279cde5492fSlogin         }
280cde5492fSlogin     }
281cde5492fSlogin 
282151251b5Slogin     /// @brief 获得当前等待队列的大小
len(&self) -> usize283151251b5Slogin     pub fn len(&self) -> usize {
284151251b5Slogin         return self.0.lock().wait_list.len();
285151251b5Slogin     }
286151251b5Slogin }
287151251b5Slogin 
288151251b5Slogin impl InnerWaitQueue {
289151251b5Slogin     pub const INIT: InnerWaitQueue = InnerWaitQueue {
290151251b5Slogin         wait_list: LinkedList::new(),
291151251b5Slogin     };
292151251b5Slogin }
29340609970SGnoCiYeH 
before_sleep_check(max_preempt: usize)29440609970SGnoCiYeH fn before_sleep_check(max_preempt: usize) {
29540609970SGnoCiYeH     let pcb = ProcessManager::current_pcb();
29640609970SGnoCiYeH     if unlikely(pcb.preempt_count() > max_preempt) {
2972eab6dd7S曾俊         warn!(
29840609970SGnoCiYeH             "Process {:?}: Try to sleep when preempt count is {}",
2998cb2e9b3SLoGin             pcb.pid().data(),
30040609970SGnoCiYeH             pcb.preempt_count()
30140609970SGnoCiYeH         );
30240609970SGnoCiYeH     }
30340609970SGnoCiYeH }
30440609970SGnoCiYeH 
30540609970SGnoCiYeH /// 事件等待队列
30640609970SGnoCiYeH #[derive(Debug)]
30740609970SGnoCiYeH pub struct EventWaitQueue {
30840609970SGnoCiYeH     wait_list: SpinLock<Vec<(u64, Arc<ProcessControlBlock>)>>,
30940609970SGnoCiYeH }
31040609970SGnoCiYeH 
311dfe53cf0SGnoCiYeH impl Default for EventWaitQueue {
default() -> Self312dfe53cf0SGnoCiYeH     fn default() -> Self {
313dfe53cf0SGnoCiYeH         Self::new()
314dfe53cf0SGnoCiYeH     }
315dfe53cf0SGnoCiYeH }
316dfe53cf0SGnoCiYeH 
317e2841179SLoGin #[allow(dead_code)]
31840609970SGnoCiYeH impl EventWaitQueue {
new() -> Self31940609970SGnoCiYeH     pub fn new() -> Self {
32040609970SGnoCiYeH         Self {
321dfe53cf0SGnoCiYeH             wait_list: SpinLock::new(Default::default()),
32240609970SGnoCiYeH         }
32340609970SGnoCiYeH     }
32440609970SGnoCiYeH 
32540609970SGnoCiYeH     /// ## 让当前进程在该队列上等待感兴趣的事件
32640609970SGnoCiYeH     ///
32740609970SGnoCiYeH     /// ### 参数
32840609970SGnoCiYeH     /// - events: 进程感兴趣的事件,events最好是为位表示,一位表示一个事件
32940609970SGnoCiYeH     ///
33040609970SGnoCiYeH     /// 注意,使用前应该注意有可能其他地方定义了冲突的事件,可能会导致未定义行为
sleep(&self, events: u64)33140609970SGnoCiYeH     pub fn sleep(&self, events: u64) {
33240609970SGnoCiYeH         before_sleep_check(0);
33340609970SGnoCiYeH         let mut guard = self.wait_list.lock_irqsave();
33440609970SGnoCiYeH         ProcessManager::mark_sleep(true).unwrap_or_else(|e| {
33540609970SGnoCiYeH             panic!("sleep error: {:?}", e);
33640609970SGnoCiYeH         });
33740609970SGnoCiYeH         guard.push((events, ProcessManager::current_pcb()));
33840609970SGnoCiYeH         drop(guard);
339f0c87a89SGnoCiYeH         schedule(SchedMode::SM_NONE);
34040609970SGnoCiYeH     }
34140609970SGnoCiYeH 
sleep_without_schedule(&self, events: u64)34240609970SGnoCiYeH     pub unsafe fn sleep_without_schedule(&self, events: u64) {
34340609970SGnoCiYeH         before_sleep_check(1);
34440609970SGnoCiYeH         let mut guard = self.wait_list.lock_irqsave();
34540609970SGnoCiYeH         ProcessManager::mark_sleep(true).unwrap_or_else(|e| {
34640609970SGnoCiYeH             panic!("sleep error: {:?}", e);
34740609970SGnoCiYeH         });
34840609970SGnoCiYeH         guard.push((events, ProcessManager::current_pcb()));
34940609970SGnoCiYeH         drop(guard);
35040609970SGnoCiYeH     }
35140609970SGnoCiYeH 
sleep_unlock_spinlock<T>(&self, events: u64, to_unlock: SpinLockGuard<T>)35240609970SGnoCiYeH     pub fn sleep_unlock_spinlock<T>(&self, events: u64, to_unlock: SpinLockGuard<T>) {
35340609970SGnoCiYeH         before_sleep_check(1);
3540d6cf65aSLoGin         let mut guard = self.wait_list.lock_irqsave();
35540609970SGnoCiYeH         let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
35640609970SGnoCiYeH         ProcessManager::mark_sleep(true).unwrap_or_else(|e| {
35740609970SGnoCiYeH             panic!("sleep error: {:?}", e);
35840609970SGnoCiYeH         });
35940609970SGnoCiYeH         drop(irq_guard);
36040609970SGnoCiYeH         guard.push((events, ProcessManager::current_pcb()));
36140609970SGnoCiYeH         drop(to_unlock);
36240609970SGnoCiYeH         drop(guard);
363f0c87a89SGnoCiYeH         schedule(SchedMode::SM_NONE);
36440609970SGnoCiYeH     }
36540609970SGnoCiYeH 
36640609970SGnoCiYeH     /// ### 唤醒该队列上等待events的进程
36740609970SGnoCiYeH     ///
36840609970SGnoCiYeH     ///  ### 参数
36940609970SGnoCiYeH     /// - events: 发生的事件
37040609970SGnoCiYeH     ///
37140609970SGnoCiYeH     /// 需要注意的是,只要触发了events中的任意一件事件,进程都会被唤醒
wakeup_any(&self, events: u64) -> usize37240609970SGnoCiYeH     pub fn wakeup_any(&self, events: u64) -> usize {
37340609970SGnoCiYeH         let mut ret = 0;
3740d6cf65aSLoGin 
3750d6cf65aSLoGin         let mut wq_guard = self.wait_list.lock_irqsave();
3760d6cf65aSLoGin         wq_guard.retain(|(es, pcb)| {
37740609970SGnoCiYeH             if *es & events > 0 {
37840609970SGnoCiYeH                 // 有感兴趣的事件
37940609970SGnoCiYeH                 if ProcessManager::wakeup(pcb).is_ok() {
38040609970SGnoCiYeH                     ret += 1;
38140609970SGnoCiYeH                     return false;
3820e7c4693SGnoCiYeH                 } else {
3830e7c4693SGnoCiYeH                     return true;
38440609970SGnoCiYeH                 }
38540609970SGnoCiYeH             } else {
3860e7c4693SGnoCiYeH                 return true;
38740609970SGnoCiYeH             }
38840609970SGnoCiYeH         });
38940609970SGnoCiYeH         ret
39040609970SGnoCiYeH     }
39140609970SGnoCiYeH 
39240609970SGnoCiYeH     /// ### 唤醒该队列上等待events的进程
39340609970SGnoCiYeH     ///
39440609970SGnoCiYeH     ///  ### 参数
39540609970SGnoCiYeH     /// - events: 发生的事件
39640609970SGnoCiYeH     ///
39740609970SGnoCiYeH     /// 需要注意的是,只有满足所有事件的进程才会被唤醒
wakeup(&self, events: u64) -> usize39840609970SGnoCiYeH     pub fn wakeup(&self, events: u64) -> usize {
39940609970SGnoCiYeH         let mut ret = 0;
4000d6cf65aSLoGin         let mut wq_guard = self.wait_list.lock_irqsave();
4010d6cf65aSLoGin         wq_guard.retain(|(es, pcb)| {
40240609970SGnoCiYeH             if *es == events {
40340609970SGnoCiYeH                 // 有感兴趣的事件
40440609970SGnoCiYeH                 if ProcessManager::wakeup(pcb).is_ok() {
40540609970SGnoCiYeH                     ret += 1;
40640609970SGnoCiYeH                     return false;
4070e7c4693SGnoCiYeH                 } else {
4080e7c4693SGnoCiYeH                     return true;
40940609970SGnoCiYeH                 }
41040609970SGnoCiYeH             } else {
4110e7c4693SGnoCiYeH                 return true;
41240609970SGnoCiYeH             }
41340609970SGnoCiYeH         });
41440609970SGnoCiYeH         ret
41540609970SGnoCiYeH     }
41640609970SGnoCiYeH 
wakeup_all(&self)41740609970SGnoCiYeH     pub fn wakeup_all(&self) {
41840609970SGnoCiYeH         self.wakeup_any(u64::MAX);
41940609970SGnoCiYeH     }
42040609970SGnoCiYeH }
421