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