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