136fd0130Shoumkh use core::{ 236fd0130Shoumkh fmt::Debug, 336fd0130Shoumkh intrinsics::unlikely, 436fd0130Shoumkh sync::atomic::{compiler_fence, AtomicBool, AtomicU64, Ordering}, 536fd0130Shoumkh }; 6bacd691cSlogin 7bacd691cSlogin use alloc::{ 8bacd691cSlogin boxed::Box, 9bacd691cSlogin sync::{Arc, Weak}, 10*b8ed3825SDonkey Kane vec::Vec, 11bacd691cSlogin }; 1291e9d4abSLoGin use system_error::SystemError; 13bacd691cSlogin 14bacd691cSlogin use crate::{ 151496ba7bSLoGin arch::{sched::sched, CurrentIrqArch}, 1636fd0130Shoumkh exception::{ 1736fd0130Shoumkh softirq::{softirq_vectors, SoftirqNumber, SoftirqVec}, 1836fd0130Shoumkh InterruptArch, 19bacd691cSlogin }, 20be8cdf4bSLoGin kerror, kinfo, 210d6cf65aSLoGin libs::spinlock::{SpinLock, SpinLockGuard}, 221496ba7bSLoGin process::{ProcessControlBlock, ProcessManager}, 23bacd691cSlogin }; 24bacd691cSlogin 25*b8ed3825SDonkey Kane use super::{jiffies::NSEC_PER_JIFFY, timekeeping::update_wall_time}; 2636fd0130Shoumkh 27bacd691cSlogin const MAX_TIMEOUT: i64 = i64::MAX; 28bacd691cSlogin const TIMER_RUN_CYCLE_THRESHOLD: usize = 20; 2936fd0130Shoumkh static TIMER_JIFFIES: AtomicU64 = AtomicU64::new(0); 30bacd691cSlogin 31bacd691cSlogin lazy_static! { 32*b8ed3825SDonkey Kane pub static ref TIMER_LIST: SpinLock<Vec<(u64, Arc<Timer>)>> = SpinLock::new(Vec::new()); 33bacd691cSlogin } 34bacd691cSlogin 35bacd691cSlogin /// 定时器要执行的函数的特征 3636fd0130Shoumkh pub trait TimerFunction: Send + Sync + Debug { 3736fd0130Shoumkh fn run(&mut self) -> Result<(), SystemError>; 38bacd691cSlogin } 39bacd691cSlogin 4036fd0130Shoumkh #[derive(Debug)] 41bacd691cSlogin /// WakeUpHelper函数对应的结构体 42bacd691cSlogin pub struct WakeUpHelper { 431496ba7bSLoGin pcb: Arc<ProcessControlBlock>, 44bacd691cSlogin } 45bacd691cSlogin 46bacd691cSlogin impl WakeUpHelper { 471496ba7bSLoGin pub fn new(pcb: Arc<ProcessControlBlock>) -> Box<WakeUpHelper> { 48bacd691cSlogin return Box::new(WakeUpHelper { pcb }); 49bacd691cSlogin } 50bacd691cSlogin } 51bacd691cSlogin 52bacd691cSlogin impl TimerFunction for WakeUpHelper { 5336fd0130Shoumkh fn run(&mut self) -> Result<(), SystemError> { 541496ba7bSLoGin ProcessManager::wakeup(&self.pcb).ok(); 5536fd0130Shoumkh return Ok(()); 56bacd691cSlogin } 57bacd691cSlogin } 58bacd691cSlogin 5936fd0130Shoumkh #[derive(Debug)] 600d6cf65aSLoGin pub struct Timer { 610d6cf65aSLoGin inner: SpinLock<InnerTimer>, 620d6cf65aSLoGin } 63bacd691cSlogin 64bacd691cSlogin impl Timer { 65bacd691cSlogin /// @brief 创建一个定时器(单位:ms) 66bacd691cSlogin /// 67bacd691cSlogin /// @param timer_func 定时器需要执行的函数对应的结构体 68bacd691cSlogin /// 69bacd691cSlogin /// @param expire_jiffies 定时器结束时刻 70bacd691cSlogin /// 71bacd691cSlogin /// @return 定时器结构体 72bacd691cSlogin pub fn new(timer_func: Box<dyn TimerFunction>, expire_jiffies: u64) -> Arc<Self> { 730d6cf65aSLoGin let result: Arc<Timer> = Arc::new(Timer { 740d6cf65aSLoGin inner: SpinLock::new(InnerTimer { 75bacd691cSlogin expire_jiffies, 760d6cf65aSLoGin timer_func: Some(timer_func), 77bacd691cSlogin self_ref: Weak::default(), 78971462beSGnoCiYeH triggered: false, 790d6cf65aSLoGin }), 800d6cf65aSLoGin }); 81bacd691cSlogin 820d6cf65aSLoGin result.inner.lock().self_ref = Arc::downgrade(&result); 83bacd691cSlogin 84bacd691cSlogin return result; 85bacd691cSlogin } 86bacd691cSlogin 870d6cf65aSLoGin pub fn inner(&self) -> SpinLockGuard<InnerTimer> { 880d6cf65aSLoGin return self.inner.lock_irqsave(); 890d6cf65aSLoGin } 900d6cf65aSLoGin 91bacd691cSlogin /// @brief 将定时器插入到定时器链表中 92bacd691cSlogin pub fn activate(&self) { 930d6cf65aSLoGin let mut timer_list = TIMER_LIST.lock_irqsave(); 940d6cf65aSLoGin let inner_guard = self.inner(); 95cde5492fSlogin 96bacd691cSlogin // 链表为空,则直接插入 97bacd691cSlogin if timer_list.is_empty() { 98bacd691cSlogin // FIXME push_timer 99*b8ed3825SDonkey Kane timer_list.push(( 100*b8ed3825SDonkey Kane inner_guard.expire_jiffies, 101*b8ed3825SDonkey Kane inner_guard.self_ref.upgrade().unwrap(), 102*b8ed3825SDonkey Kane )); 103cde5492fSlogin 104cde5492fSlogin drop(inner_guard); 105cde5492fSlogin drop(timer_list); 106cde5492fSlogin compiler_fence(Ordering::SeqCst); 107cde5492fSlogin 108bacd691cSlogin return; 109bacd691cSlogin } 110*b8ed3825SDonkey Kane let expire_jiffies = inner_guard.expire_jiffies; 111*b8ed3825SDonkey Kane let self_arc = inner_guard.self_ref.upgrade().unwrap(); 112*b8ed3825SDonkey Kane drop(inner_guard); 113bacd691cSlogin let mut split_pos: usize = 0; 114bacd691cSlogin for (pos, elt) in timer_list.iter().enumerate() { 115*b8ed3825SDonkey Kane if Arc::ptr_eq(&self_arc, &elt.1) { 116*b8ed3825SDonkey Kane kwarn!("Timer already in list"); 117*b8ed3825SDonkey Kane } 118*b8ed3825SDonkey Kane if elt.0 > expire_jiffies { 119bacd691cSlogin split_pos = pos; 120bacd691cSlogin break; 121bacd691cSlogin } 122bacd691cSlogin } 123*b8ed3825SDonkey Kane timer_list.insert(split_pos, (expire_jiffies, self_arc)); 124*b8ed3825SDonkey Kane 125cde5492fSlogin drop(timer_list); 126bacd691cSlogin } 127bacd691cSlogin 128bacd691cSlogin #[inline] 129bacd691cSlogin fn run(&self) { 1300d6cf65aSLoGin let mut timer = self.inner(); 131971462beSGnoCiYeH timer.triggered = true; 1320d6cf65aSLoGin let func = timer.timer_func.take(); 1330d6cf65aSLoGin drop(timer); 1340d6cf65aSLoGin let r = func.map(|mut f| f.run()).unwrap_or(Ok(())); 13536fd0130Shoumkh if unlikely(r.is_err()) { 13636fd0130Shoumkh kerror!( 13736fd0130Shoumkh "Failed to run timer function: {self:?} {:?}", 1388d72b68dSJomo r.as_ref().err().unwrap() 13936fd0130Shoumkh ); 14036fd0130Shoumkh } 141bacd691cSlogin } 142971462beSGnoCiYeH 143971462beSGnoCiYeH /// ## 判断定时器是否已经触发 144971462beSGnoCiYeH pub fn timeout(&self) -> bool { 1450d6cf65aSLoGin self.inner().triggered 146971462beSGnoCiYeH } 147971462beSGnoCiYeH 148971462beSGnoCiYeH /// ## 取消定时器任务 149971462beSGnoCiYeH pub fn cancel(&self) -> bool { 1500d6cf65aSLoGin let this_arc = self.inner().self_ref.upgrade().unwrap(); 151971462beSGnoCiYeH TIMER_LIST 1520d6cf65aSLoGin .lock_irqsave() 153*b8ed3825SDonkey Kane .extract_if(|x| Arc::ptr_eq(&this_arc, &x.1)) 154840045afSLoGin .for_each(drop); 155971462beSGnoCiYeH true 156971462beSGnoCiYeH } 157bacd691cSlogin } 158bacd691cSlogin 159bacd691cSlogin /// 定时器类型 16036fd0130Shoumkh #[derive(Debug)] 161bacd691cSlogin pub struct InnerTimer { 162bacd691cSlogin /// 定时器结束时刻 163bacd691cSlogin pub expire_jiffies: u64, 164bacd691cSlogin /// 定时器需要执行的函数结构体 1650d6cf65aSLoGin pub timer_func: Option<Box<dyn TimerFunction>>, 166bacd691cSlogin /// self_ref 167bacd691cSlogin self_ref: Weak<Timer>, 168971462beSGnoCiYeH /// 判断该计时器是否触发 169971462beSGnoCiYeH triggered: bool, 170bacd691cSlogin } 171bacd691cSlogin 172bacd691cSlogin #[derive(Debug)] 173bacd691cSlogin pub struct DoTimerSoftirq { 174bacd691cSlogin running: AtomicBool, 175bacd691cSlogin } 176bacd691cSlogin 177bacd691cSlogin impl DoTimerSoftirq { 178bacd691cSlogin pub fn new() -> Self { 179bacd691cSlogin return DoTimerSoftirq { 180bacd691cSlogin running: AtomicBool::new(false), 181bacd691cSlogin }; 182bacd691cSlogin } 183bacd691cSlogin 184bacd691cSlogin fn set_run(&self) -> bool { 185bacd691cSlogin let x = self 186bacd691cSlogin .running 187bacd691cSlogin .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed); 188840045afSLoGin return x.is_ok(); 189bacd691cSlogin } 190bacd691cSlogin 191bacd691cSlogin fn clear_run(&self) { 192bacd691cSlogin self.running.store(false, Ordering::Release); 193bacd691cSlogin } 194bacd691cSlogin } 195bacd691cSlogin impl SoftirqVec for DoTimerSoftirq { 196bacd691cSlogin fn run(&self) { 197840045afSLoGin if !self.set_run() { 198bacd691cSlogin return; 199bacd691cSlogin } 200bacd691cSlogin // 最多只处理TIMER_RUN_CYCLE_THRESHOLD个计时器 201bacd691cSlogin for _ in 0..TIMER_RUN_CYCLE_THRESHOLD { 202bacd691cSlogin // kdebug!("DoTimerSoftirq run"); 2030d6cf65aSLoGin let timer_list = TIMER_LIST.try_lock_irqsave(); 204cde5492fSlogin if timer_list.is_err() { 205cde5492fSlogin continue; 206cde5492fSlogin } 207cde5492fSlogin let mut timer_list = timer_list.unwrap(); 208bacd691cSlogin 209bacd691cSlogin if timer_list.is_empty() { 210bacd691cSlogin break; 211bacd691cSlogin } 212bacd691cSlogin 213*b8ed3825SDonkey Kane let (front_jiffies, timer_list_front) = timer_list.first().unwrap().clone(); 214cde5492fSlogin // kdebug!("to lock timer_list_front"); 215*b8ed3825SDonkey Kane 216*b8ed3825SDonkey Kane if front_jiffies >= TIMER_JIFFIES.load(Ordering::SeqCst) { 217cde5492fSlogin break; 218cde5492fSlogin } 219*b8ed3825SDonkey Kane timer_list.remove(0); 220cde5492fSlogin drop(timer_list); 221cde5492fSlogin timer_list_front.run(); 222bacd691cSlogin } 223bacd691cSlogin 224bacd691cSlogin self.clear_run(); 225bacd691cSlogin } 226bacd691cSlogin } 227bacd691cSlogin 2285b59005fSLoGin /// 初始化系统定时器 2295b59005fSLoGin #[inline(never)] 230bacd691cSlogin pub fn timer_init() { 231bacd691cSlogin // FIXME 调用register_trap 232bacd691cSlogin let do_timer_softirq = Arc::new(DoTimerSoftirq::new()); 233bacd691cSlogin softirq_vectors() 234bacd691cSlogin .register_softirq(SoftirqNumber::TIMER, do_timer_softirq) 235bacd691cSlogin .expect("Failed to register timer softirq"); 23640fe15e0SLoGin kinfo!("timer initialized successfully"); 237bacd691cSlogin } 238bacd691cSlogin 239bacd691cSlogin /// 计算接下来n毫秒对应的定时器时间片 240bacd691cSlogin pub fn next_n_ms_timer_jiffies(expire_ms: u64) -> u64 { 241*b8ed3825SDonkey Kane return TIMER_JIFFIES.load(Ordering::SeqCst) + expire_ms * 1000000 / NSEC_PER_JIFFY as u64; 242bacd691cSlogin } 243bacd691cSlogin /// 计算接下来n微秒对应的定时器时间片 244bacd691cSlogin pub fn next_n_us_timer_jiffies(expire_us: u64) -> u64 { 245*b8ed3825SDonkey Kane return TIMER_JIFFIES.load(Ordering::SeqCst) + expire_us * 1000 / NSEC_PER_JIFFY as u64; 246bacd691cSlogin } 247bacd691cSlogin 248bacd691cSlogin /// @brief 让pcb休眠timeout个jiffies 249bacd691cSlogin /// 250bacd691cSlogin /// @param timeout 需要休眠的时间(单位:jiffies) 251bacd691cSlogin /// 252bacd691cSlogin /// @return Ok(i64) 剩余需要休眠的时间(单位:jiffies) 253bacd691cSlogin /// 254bacd691cSlogin /// @return Err(SystemError) 错误码 255bacd691cSlogin pub fn schedule_timeout(mut timeout: i64) -> Result<i64, SystemError> { 256bacd691cSlogin // kdebug!("schedule_timeout"); 257bacd691cSlogin if timeout == MAX_TIMEOUT { 2588cb2e9b3SLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 259be8cdf4bSLoGin ProcessManager::mark_sleep(true).ok(); 2608cb2e9b3SLoGin drop(irq_guard); 261bacd691cSlogin sched(); 262bacd691cSlogin return Ok(MAX_TIMEOUT); 263bacd691cSlogin } else if timeout < 0 { 264bacd691cSlogin kerror!("timeout can't less than 0"); 265bacd691cSlogin return Err(SystemError::EINVAL); 266bacd691cSlogin } else { 267bacd691cSlogin // 禁用中断,防止在这段期间发生调度,造成死锁 26836fd0130Shoumkh let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 26936fd0130Shoumkh 27036fd0130Shoumkh timeout += TIMER_JIFFIES.load(Ordering::SeqCst) as i64; 2711496ba7bSLoGin let timer = Timer::new( 2721496ba7bSLoGin WakeUpHelper::new(ProcessManager::current_pcb()), 2731496ba7bSLoGin timeout as u64, 2741496ba7bSLoGin ); 2751496ba7bSLoGin ProcessManager::mark_sleep(true).ok(); 276bacd691cSlogin timer.activate(); 27736fd0130Shoumkh 27836fd0130Shoumkh drop(irq_guard); 279bacd691cSlogin 280bacd691cSlogin sched(); 28136fd0130Shoumkh let time_remaining: i64 = timeout - TIMER_JIFFIES.load(Ordering::SeqCst) as i64; 282bacd691cSlogin if time_remaining >= 0 { 283bacd691cSlogin // 被提前唤醒,返回剩余时间 284bacd691cSlogin return Ok(time_remaining); 285bacd691cSlogin } else { 286bacd691cSlogin return Ok(0); 287bacd691cSlogin } 288bacd691cSlogin } 289bacd691cSlogin } 290bacd691cSlogin 291bacd691cSlogin pub fn timer_get_first_expire() -> Result<u64, SystemError> { 292bacd691cSlogin // FIXME 293bacd691cSlogin // kdebug!("rs_timer_get_first_expire,timer_jif = {:?}", TIMER_JIFFIES); 294bacd691cSlogin for _ in 0..10 { 295be8cdf4bSLoGin match TIMER_LIST.try_lock_irqsave() { 296bacd691cSlogin Ok(timer_list) => { 297bacd691cSlogin // kdebug!("rs_timer_get_first_expire TIMER_LIST lock successfully"); 298bacd691cSlogin if timer_list.is_empty() { 299bacd691cSlogin // kdebug!("timer_list is empty"); 300bacd691cSlogin return Ok(0); 301bacd691cSlogin } else { 302bacd691cSlogin // kdebug!("timer_list not empty"); 303*b8ed3825SDonkey Kane return Ok(timer_list.first().unwrap().0); 304bacd691cSlogin } 305bacd691cSlogin } 306bacd691cSlogin // 加锁失败返回啥?? 307bacd691cSlogin Err(_) => continue, 308bacd691cSlogin } 309bacd691cSlogin } 31079a452ceShoumkh return Err(SystemError::EAGAIN_OR_EWOULDBLOCK); 311bacd691cSlogin } 312bacd691cSlogin 313be8cdf4bSLoGin /// 更新系统时间片 3140d6cf65aSLoGin pub fn update_timer_jiffies(add_jiffies: u64, time_us: i64) -> u64 { 31536fd0130Shoumkh let prev = TIMER_JIFFIES.fetch_add(add_jiffies, Ordering::SeqCst); 31636fd0130Shoumkh compiler_fence(Ordering::SeqCst); 3170d6cf65aSLoGin update_wall_time(time_us); 31836fd0130Shoumkh 31936fd0130Shoumkh compiler_fence(Ordering::SeqCst); 32036fd0130Shoumkh return prev + add_jiffies; 321bacd691cSlogin } 32236fd0130Shoumkh 323bacd691cSlogin pub fn clock() -> u64 { 32436fd0130Shoumkh return TIMER_JIFFIES.load(Ordering::SeqCst); 325bacd691cSlogin } 326bacd691cSlogin 327bacd691cSlogin // ====== 以下为给C提供的接口 ====== 328bacd691cSlogin 329bacd691cSlogin #[no_mangle] 330bacd691cSlogin pub extern "C" fn rs_timer_init() { 331bacd691cSlogin timer_init(); 332bacd691cSlogin } 333