xref: /DragonOS/kernel/src/sched/completion.rs (revision 91e9d4ab55ef960f57a1b6287bc523ca4341f67a)
1 #![allow(dead_code)]
2 use system_error::SystemError;
3 
4 use crate::{
5     libs::{spinlock::SpinLock, wait_queue::WaitQueue},
6     time::timer::schedule_timeout,
7 };
8 
9 const COMPLETE_ALL: u32 = core::u32::MAX;
10 const MAX_TIMEOUT: i64 = core::i64::MAX;
11 
12 #[derive(Debug)]
13 pub struct Completion {
14     inner: SpinLock<InnerCompletion>,
15 }
16 
17 impl Completion {
18     pub const fn new() -> Self {
19         Self {
20             inner: SpinLock::new(InnerCompletion::new()),
21         }
22     }
23 
24     /// @brief 基本函数:通用的处理wait命令的函数(即所有wait_for_completion函数最核心部分在这里)
25     ///
26     /// @param timeout 非负整数
27     /// @param interuptible 设置进程是否能被打断
28     /// @return 返回剩余时间或者SystemError
29     fn do_wait_for_common(&self, mut timeout: i64, interuptible: bool) -> Result<i64, SystemError> {
30         let mut inner = self.inner.lock_irqsave();
31 
32         if inner.done == 0 {
33             //loop break 类似 do while 保证进行一次信号检测
34             loop {
35                 //检查当前线程是否有未处理的信号
36                 //             if (signal_pending_state(state, current)) {
37                 // timeout = -ERESTARTSYS;
38                 // break;
39                 //}
40 
41                 if interuptible {
42                     unsafe { inner.wait_queue.sleep_without_schedule() };
43                 } else {
44                     unsafe { inner.wait_queue.sleep_without_schedule_uninterruptible() };
45                 }
46                 drop(inner);
47                 timeout = schedule_timeout(timeout)?;
48                 inner = self.inner.lock_irqsave();
49                 if inner.done != 0 || timeout <= 0 {
50                     break;
51                 }
52             }
53             inner.wait_queue.wakeup(None);
54             if inner.done == 0 {
55                 drop(inner);
56                 return Ok(timeout);
57             }
58         }
59         if inner.done != COMPLETE_ALL {
60             inner.done -= 1;
61         }
62         drop(inner);
63         return Ok(if timeout > 0 { timeout } else { 1 });
64     }
65 
66     /// @brief 等待指定时间,超时后就返回, 同时设置pcb state为uninteruptible.
67     /// @param timeout 非负整数,等待指定时间,超时后就返回/或者提前done
68     pub fn wait_for_completion_timeout(&self, timeout: i64) -> Result<i64, SystemError> {
69         self.do_wait_for_common(timeout, false)
70     }
71 
72     /// @brief 等待completion命令唤醒进程, 同时设置pcb state 为uninteruptible.
73     pub fn wait_for_completion(&self) -> Result<i64, SystemError> {
74         self.do_wait_for_common(MAX_TIMEOUT, false)
75     }
76 
77     /// @brief @brief 等待completion的完成,但是可以被中断
78     pub fn wait_for_completion_interruptible(&self) -> Result<i64, SystemError> {
79         self.do_wait_for_common(MAX_TIMEOUT, true)
80     }
81 
82     pub fn wait_for_completion_interruptible_timeout(
83         &mut self,
84         timeout: i64,
85     ) -> Result<i64, SystemError> {
86         assert!(timeout >= 0);
87         self.do_wait_for_common(timeout, true)
88     }
89 
90     /// @brief 唤醒一个wait_queue中的节点
91     pub fn complete(&self) {
92         let mut inner = self.inner.lock_irqsave();
93         if inner.done != COMPLETE_ALL {
94             inner.done += 1;
95         }
96         inner.wait_queue.wakeup(None);
97         // 脱离生命周期,自动释放guard
98     }
99 
100     /// @brief 永久标记done为Complete_All,并从wait_queue中删除所有节点
101     pub fn complete_all(&self) {
102         let mut inner = self.inner.lock_irqsave();
103         inner.done = COMPLETE_ALL;
104         inner.wait_queue.wakeup_all(None);
105         // 脱离生命周期,自动释放guard
106     }
107 
108     /// @brief @brief 尝试获取completion的一个done!如果您在wait之前加上这个函数作为判断,说不定会加快运行速度。
109     ///
110     /// @return true - 表示不需要wait_for_completion,并且已经获取到了一个completion(即返回true意味着done已经被 减1 )
111     /// @return false - 表示当前done=0,您需要进入等待,即wait_for_completion
112     pub fn try_wait_for_completion(&mut self) -> bool {
113         let mut inner = self.inner.lock_irqsave();
114         if inner.done == 0 {
115             return false;
116         }
117 
118         if inner.done != 0 {
119             return false;
120         } else if inner.done != COMPLETE_ALL {
121             inner.done -= 1;
122         }
123         return true;
124         // 脱离生命周期,自动释放guard
125     }
126 
127     // @brief 测试一个completion是否有waiter。(即done是不是等于0)
128     pub fn completion_done(&self) -> bool {
129         let inner = self.inner.lock_irqsave();
130         if inner.done == 0 {
131             return false;
132         }
133 
134         if inner.done == 0 {
135             return false;
136         }
137         return true;
138         // 脱离生命周期,自动释放guard
139     }
140 }
141 #[derive(Debug)]
142 pub struct InnerCompletion {
143     done: u32,
144     wait_queue: WaitQueue,
145 }
146 
147 impl InnerCompletion {
148     pub const fn new() -> Self {
149         Self {
150             done: 0,
151             wait_queue: WaitQueue::INIT,
152         }
153     }
154 }
155