xref: /DragonOS/kernel/src/sched/completion.rs (revision b5b571e02693d91eb6918d3b7561e088c3e7ee81)
11496ba7bSLoGin #![allow(dead_code)]
2*b5b571e0SLoGin 
391e9d4abSLoGin use system_error::SystemError;
491e9d4abSLoGin 
51496ba7bSLoGin use crate::{
61496ba7bSLoGin     libs::{spinlock::SpinLock, wait_queue::WaitQueue},
71496ba7bSLoGin     time::timer::schedule_timeout,
81496ba7bSLoGin };
91496ba7bSLoGin 
101496ba7bSLoGin const COMPLETE_ALL: u32 = core::u32::MAX;
111496ba7bSLoGin const MAX_TIMEOUT: i64 = core::i64::MAX;
121496ba7bSLoGin 
131496ba7bSLoGin #[derive(Debug)]
141496ba7bSLoGin pub struct Completion {
151496ba7bSLoGin     inner: SpinLock<InnerCompletion>,
161496ba7bSLoGin }
171496ba7bSLoGin 
181496ba7bSLoGin impl Completion {
191496ba7bSLoGin     pub const fn new() -> Self {
201496ba7bSLoGin         Self {
211496ba7bSLoGin             inner: SpinLock::new(InnerCompletion::new()),
221496ba7bSLoGin         }
231496ba7bSLoGin     }
241496ba7bSLoGin 
251496ba7bSLoGin     /// @brief 基本函数:通用的处理wait命令的函数(即所有wait_for_completion函数最核心部分在这里)
261496ba7bSLoGin     ///
271496ba7bSLoGin     /// @param timeout 非负整数
281496ba7bSLoGin     /// @param interuptible 设置进程是否能被打断
291496ba7bSLoGin     /// @return 返回剩余时间或者SystemError
301496ba7bSLoGin     fn do_wait_for_common(&self, mut timeout: i64, interuptible: bool) -> Result<i64, SystemError> {
311496ba7bSLoGin         let mut inner = self.inner.lock_irqsave();
321496ba7bSLoGin 
331496ba7bSLoGin         if inner.done == 0 {
341496ba7bSLoGin             //loop break 类似 do while 保证进行一次信号检测
351496ba7bSLoGin             loop {
361496ba7bSLoGin                 //检查当前线程是否有未处理的信号
371496ba7bSLoGin                 //             if (signal_pending_state(state, current)) {
381496ba7bSLoGin                 // timeout = -ERESTARTSYS;
391496ba7bSLoGin                 // break;
401496ba7bSLoGin                 //}
411496ba7bSLoGin 
421496ba7bSLoGin                 if interuptible {
431496ba7bSLoGin                     unsafe { inner.wait_queue.sleep_without_schedule() };
441496ba7bSLoGin                 } else {
451496ba7bSLoGin                     unsafe { inner.wait_queue.sleep_without_schedule_uninterruptible() };
461496ba7bSLoGin                 }
471496ba7bSLoGin                 drop(inner);
481496ba7bSLoGin                 timeout = schedule_timeout(timeout)?;
491496ba7bSLoGin                 inner = self.inner.lock_irqsave();
501496ba7bSLoGin                 if inner.done != 0 || timeout <= 0 {
511496ba7bSLoGin                     break;
521496ba7bSLoGin                 }
531496ba7bSLoGin             }
541496ba7bSLoGin             inner.wait_queue.wakeup(None);
551496ba7bSLoGin             if inner.done == 0 {
561496ba7bSLoGin                 drop(inner);
571496ba7bSLoGin                 return Ok(timeout);
581496ba7bSLoGin             }
591496ba7bSLoGin         }
601496ba7bSLoGin         if inner.done != COMPLETE_ALL {
611496ba7bSLoGin             inner.done -= 1;
621496ba7bSLoGin         }
631496ba7bSLoGin         drop(inner);
641496ba7bSLoGin         return Ok(if timeout > 0 { timeout } else { 1 });
651496ba7bSLoGin     }
661496ba7bSLoGin 
671496ba7bSLoGin     /// @brief 等待指定时间,超时后就返回, 同时设置pcb state为uninteruptible.
681496ba7bSLoGin     /// @param timeout 非负整数,等待指定时间,超时后就返回/或者提前done
691496ba7bSLoGin     pub fn wait_for_completion_timeout(&self, timeout: i64) -> Result<i64, SystemError> {
701496ba7bSLoGin         self.do_wait_for_common(timeout, false)
711496ba7bSLoGin     }
721496ba7bSLoGin 
731496ba7bSLoGin     /// @brief 等待completion命令唤醒进程, 同时设置pcb state 为uninteruptible.
741496ba7bSLoGin     pub fn wait_for_completion(&self) -> Result<i64, SystemError> {
751496ba7bSLoGin         self.do_wait_for_common(MAX_TIMEOUT, false)
761496ba7bSLoGin     }
771496ba7bSLoGin 
781496ba7bSLoGin     /// @brief @brief 等待completion的完成,但是可以被中断
791496ba7bSLoGin     pub fn wait_for_completion_interruptible(&self) -> Result<i64, SystemError> {
801496ba7bSLoGin         self.do_wait_for_common(MAX_TIMEOUT, true)
811496ba7bSLoGin     }
821496ba7bSLoGin 
831496ba7bSLoGin     pub fn wait_for_completion_interruptible_timeout(
841496ba7bSLoGin         &mut self,
851496ba7bSLoGin         timeout: i64,
861496ba7bSLoGin     ) -> Result<i64, SystemError> {
871496ba7bSLoGin         assert!(timeout >= 0);
881496ba7bSLoGin         self.do_wait_for_common(timeout, true)
891496ba7bSLoGin     }
901496ba7bSLoGin 
911496ba7bSLoGin     /// @brief 唤醒一个wait_queue中的节点
921496ba7bSLoGin     pub fn complete(&self) {
931496ba7bSLoGin         let mut inner = self.inner.lock_irqsave();
941496ba7bSLoGin         if inner.done != COMPLETE_ALL {
95*b5b571e0SLoGin             inner.done = inner.done.saturating_add(1);
961496ba7bSLoGin         }
971496ba7bSLoGin         inner.wait_queue.wakeup(None);
981496ba7bSLoGin         // 脱离生命周期,自动释放guard
991496ba7bSLoGin     }
1001496ba7bSLoGin 
1011496ba7bSLoGin     /// @brief 永久标记done为Complete_All,并从wait_queue中删除所有节点
102971462beSGnoCiYeH     pub fn complete_all(&self) {
1031496ba7bSLoGin         let mut inner = self.inner.lock_irqsave();
1041496ba7bSLoGin         inner.done = COMPLETE_ALL;
1051496ba7bSLoGin         inner.wait_queue.wakeup_all(None);
1061496ba7bSLoGin         // 脱离生命周期,自动释放guard
1071496ba7bSLoGin     }
1081496ba7bSLoGin 
1091496ba7bSLoGin     /// @brief @brief 尝试获取completion的一个done!如果您在wait之前加上这个函数作为判断,说不定会加快运行速度。
1101496ba7bSLoGin     ///
1111496ba7bSLoGin     /// @return true - 表示不需要wait_for_completion,并且已经获取到了一个completion(即返回true意味着done已经被 减1 )
1121496ba7bSLoGin     /// @return false - 表示当前done=0,您需要进入等待,即wait_for_completion
1131496ba7bSLoGin     pub fn try_wait_for_completion(&mut self) -> bool {
1141496ba7bSLoGin         let mut inner = self.inner.lock_irqsave();
1151496ba7bSLoGin         if inner.done == 0 {
1161496ba7bSLoGin             return false;
1171496ba7bSLoGin         }
1181496ba7bSLoGin 
1191496ba7bSLoGin         if inner.done != 0 {
1201496ba7bSLoGin             return false;
1211496ba7bSLoGin         } else if inner.done != COMPLETE_ALL {
1221496ba7bSLoGin             inner.done -= 1;
1231496ba7bSLoGin         }
1241496ba7bSLoGin         return true;
1251496ba7bSLoGin         // 脱离生命周期,自动释放guard
1261496ba7bSLoGin     }
1271496ba7bSLoGin 
1281496ba7bSLoGin     // @brief 测试一个completion是否有waiter。(即done是不是等于0)
1291496ba7bSLoGin     pub fn completion_done(&self) -> bool {
1301496ba7bSLoGin         let inner = self.inner.lock_irqsave();
1311496ba7bSLoGin         if inner.done == 0 {
1321496ba7bSLoGin             return false;
1331496ba7bSLoGin         }
1341496ba7bSLoGin 
1351496ba7bSLoGin         if inner.done == 0 {
1361496ba7bSLoGin             return false;
1371496ba7bSLoGin         }
1381496ba7bSLoGin         return true;
1391496ba7bSLoGin         // 脱离生命周期,自动释放guard
1401496ba7bSLoGin     }
1411496ba7bSLoGin }
1421496ba7bSLoGin #[derive(Debug)]
1431496ba7bSLoGin pub struct InnerCompletion {
1441496ba7bSLoGin     done: u32,
1451496ba7bSLoGin     wait_queue: WaitQueue,
1461496ba7bSLoGin }
1471496ba7bSLoGin 
1481496ba7bSLoGin impl InnerCompletion {
1491496ba7bSLoGin     pub const fn new() -> Self {
1501496ba7bSLoGin         Self {
1511496ba7bSLoGin             done: 0,
152*b5b571e0SLoGin             wait_queue: WaitQueue::default(),
1531496ba7bSLoGin         }
1541496ba7bSLoGin     }
1551496ba7bSLoGin }
156