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}, 10b8ed3825SDonkey Kane vec::Vec, 11bacd691cSlogin }; 1291e9d4abSLoGin use system_error::SystemError; 13bacd691cSlogin 14bacd691cSlogin use crate::{ 15f0c87a89SGnoCiYeH arch::CurrentIrqArch, 1636fd0130Shoumkh exception::{ 1736fd0130Shoumkh softirq::{softirq_vectors, SoftirqNumber, SoftirqVec}, 1836fd0130Shoumkh InterruptArch, 19bacd691cSlogin }, 20be8cdf4bSLoGin kerror, kinfo, 210d6cf65aSLoGin libs::spinlock::{SpinLock, SpinLockGuard}, 221496ba7bSLoGin process::{ProcessControlBlock, ProcessManager}, 23f0c87a89SGnoCiYeH sched::{schedule, SchedMode}, 24bacd691cSlogin }; 25bacd691cSlogin 26b8ed3825SDonkey Kane use super::{jiffies::NSEC_PER_JIFFY, timekeeping::update_wall_time}; 2736fd0130Shoumkh 28bacd691cSlogin const MAX_TIMEOUT: i64 = i64::MAX; 29bacd691cSlogin const TIMER_RUN_CYCLE_THRESHOLD: usize = 20; 3036fd0130Shoumkh static TIMER_JIFFIES: AtomicU64 = AtomicU64::new(0); 31bacd691cSlogin 32bacd691cSlogin lazy_static! { 33b8ed3825SDonkey Kane pub static ref TIMER_LIST: SpinLock<Vec<(u64, Arc<Timer>)>> = SpinLock::new(Vec::new()); 34bacd691cSlogin } 35bacd691cSlogin 36bacd691cSlogin /// 定时器要执行的函数的特征 3736fd0130Shoumkh pub trait TimerFunction: Send + Sync + Debug { 3836fd0130Shoumkh fn run(&mut self) -> Result<(), SystemError>; 39bacd691cSlogin } 40bacd691cSlogin 4136fd0130Shoumkh #[derive(Debug)] 42bacd691cSlogin /// WakeUpHelper函数对应的结构体 43bacd691cSlogin pub struct WakeUpHelper { 441496ba7bSLoGin pcb: Arc<ProcessControlBlock>, 45bacd691cSlogin } 46bacd691cSlogin 47bacd691cSlogin impl WakeUpHelper { 481496ba7bSLoGin pub fn new(pcb: Arc<ProcessControlBlock>) -> Box<WakeUpHelper> { 49bacd691cSlogin return Box::new(WakeUpHelper { pcb }); 50bacd691cSlogin } 51bacd691cSlogin } 52bacd691cSlogin 53bacd691cSlogin impl TimerFunction for WakeUpHelper { 5436fd0130Shoumkh fn run(&mut self) -> Result<(), SystemError> { 551496ba7bSLoGin ProcessManager::wakeup(&self.pcb).ok(); 5636fd0130Shoumkh return Ok(()); 57bacd691cSlogin } 58bacd691cSlogin } 59bacd691cSlogin 6036fd0130Shoumkh #[derive(Debug)] 610d6cf65aSLoGin pub struct Timer { 620d6cf65aSLoGin inner: SpinLock<InnerTimer>, 630d6cf65aSLoGin } 64bacd691cSlogin 65bacd691cSlogin impl Timer { 66bacd691cSlogin /// @brief 创建一个定时器(单位:ms) 67bacd691cSlogin /// 68bacd691cSlogin /// @param timer_func 定时器需要执行的函数对应的结构体 69bacd691cSlogin /// 70bacd691cSlogin /// @param expire_jiffies 定时器结束时刻 71bacd691cSlogin /// 72bacd691cSlogin /// @return 定时器结构体 73bacd691cSlogin pub fn new(timer_func: Box<dyn TimerFunction>, expire_jiffies: u64) -> Arc<Self> { 740d6cf65aSLoGin let result: Arc<Timer> = Arc::new(Timer { 750d6cf65aSLoGin inner: SpinLock::new(InnerTimer { 76bacd691cSlogin expire_jiffies, 770d6cf65aSLoGin timer_func: Some(timer_func), 78bacd691cSlogin self_ref: Weak::default(), 79971462beSGnoCiYeH triggered: false, 800d6cf65aSLoGin }), 810d6cf65aSLoGin }); 82bacd691cSlogin 830d6cf65aSLoGin result.inner.lock().self_ref = Arc::downgrade(&result); 84bacd691cSlogin 85bacd691cSlogin return result; 86bacd691cSlogin } 87bacd691cSlogin 880d6cf65aSLoGin pub fn inner(&self) -> SpinLockGuard<InnerTimer> { 890d6cf65aSLoGin return self.inner.lock_irqsave(); 900d6cf65aSLoGin } 910d6cf65aSLoGin 92bacd691cSlogin /// @brief 将定时器插入到定时器链表中 93bacd691cSlogin pub fn activate(&self) { 940d6cf65aSLoGin let mut timer_list = TIMER_LIST.lock_irqsave(); 950d6cf65aSLoGin let inner_guard = self.inner(); 96cde5492fSlogin 97bacd691cSlogin // 链表为空,则直接插入 98bacd691cSlogin if timer_list.is_empty() { 99bacd691cSlogin // FIXME push_timer 100b8ed3825SDonkey Kane timer_list.push(( 101b8ed3825SDonkey Kane inner_guard.expire_jiffies, 102b8ed3825SDonkey Kane inner_guard.self_ref.upgrade().unwrap(), 103b8ed3825SDonkey Kane )); 104cde5492fSlogin 105cde5492fSlogin drop(inner_guard); 106cde5492fSlogin drop(timer_list); 107cde5492fSlogin compiler_fence(Ordering::SeqCst); 108cde5492fSlogin 109bacd691cSlogin return; 110bacd691cSlogin } 111b8ed3825SDonkey Kane let expire_jiffies = inner_guard.expire_jiffies; 112b8ed3825SDonkey Kane let self_arc = inner_guard.self_ref.upgrade().unwrap(); 113b8ed3825SDonkey Kane drop(inner_guard); 114bacd691cSlogin let mut split_pos: usize = 0; 115bacd691cSlogin for (pos, elt) in timer_list.iter().enumerate() { 116b8ed3825SDonkey Kane if Arc::ptr_eq(&self_arc, &elt.1) { 117b8ed3825SDonkey Kane kwarn!("Timer already in list"); 118b8ed3825SDonkey Kane } 119b8ed3825SDonkey Kane if elt.0 > expire_jiffies { 120bacd691cSlogin split_pos = pos; 121bacd691cSlogin break; 122bacd691cSlogin } 123bacd691cSlogin } 124b8ed3825SDonkey Kane timer_list.insert(split_pos, (expire_jiffies, self_arc)); 125b8ed3825SDonkey Kane 126cde5492fSlogin drop(timer_list); 127bacd691cSlogin } 128bacd691cSlogin 129bacd691cSlogin #[inline] 130bacd691cSlogin fn run(&self) { 1310d6cf65aSLoGin let mut timer = self.inner(); 132971462beSGnoCiYeH timer.triggered = true; 1330d6cf65aSLoGin let func = timer.timer_func.take(); 1340d6cf65aSLoGin drop(timer); 1350d6cf65aSLoGin let r = func.map(|mut f| f.run()).unwrap_or(Ok(())); 13636fd0130Shoumkh if unlikely(r.is_err()) { 13736fd0130Shoumkh kerror!( 13836fd0130Shoumkh "Failed to run timer function: {self:?} {:?}", 1398d72b68dSJomo r.as_ref().err().unwrap() 14036fd0130Shoumkh ); 14136fd0130Shoumkh } 142bacd691cSlogin } 143971462beSGnoCiYeH 144971462beSGnoCiYeH /// ## 判断定时器是否已经触发 145971462beSGnoCiYeH pub fn timeout(&self) -> bool { 1460d6cf65aSLoGin self.inner().triggered 147971462beSGnoCiYeH } 148971462beSGnoCiYeH 149971462beSGnoCiYeH /// ## 取消定时器任务 150971462beSGnoCiYeH pub fn cancel(&self) -> bool { 1510d6cf65aSLoGin let this_arc = self.inner().self_ref.upgrade().unwrap(); 152971462beSGnoCiYeH TIMER_LIST 1530d6cf65aSLoGin .lock_irqsave() 154b8ed3825SDonkey Kane .extract_if(|x| Arc::ptr_eq(&this_arc, &x.1)) 155840045afSLoGin .for_each(drop); 156971462beSGnoCiYeH true 157971462beSGnoCiYeH } 158bacd691cSlogin } 159bacd691cSlogin 160bacd691cSlogin /// 定时器类型 16136fd0130Shoumkh #[derive(Debug)] 162bacd691cSlogin pub struct InnerTimer { 163bacd691cSlogin /// 定时器结束时刻 164bacd691cSlogin pub expire_jiffies: u64, 165bacd691cSlogin /// 定时器需要执行的函数结构体 1660d6cf65aSLoGin pub timer_func: Option<Box<dyn TimerFunction>>, 167bacd691cSlogin /// self_ref 168bacd691cSlogin self_ref: Weak<Timer>, 169971462beSGnoCiYeH /// 判断该计时器是否触发 170971462beSGnoCiYeH triggered: bool, 171bacd691cSlogin } 172bacd691cSlogin 173bacd691cSlogin #[derive(Debug)] 174bacd691cSlogin pub struct DoTimerSoftirq { 175bacd691cSlogin running: AtomicBool, 176bacd691cSlogin } 177bacd691cSlogin 178bacd691cSlogin impl DoTimerSoftirq { 179bacd691cSlogin pub fn new() -> Self { 180bacd691cSlogin return DoTimerSoftirq { 181bacd691cSlogin running: AtomicBool::new(false), 182bacd691cSlogin }; 183bacd691cSlogin } 184bacd691cSlogin 185bacd691cSlogin fn set_run(&self) -> bool { 186bacd691cSlogin let x = self 187bacd691cSlogin .running 188bacd691cSlogin .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed); 189840045afSLoGin return x.is_ok(); 190bacd691cSlogin } 191bacd691cSlogin 192bacd691cSlogin fn clear_run(&self) { 193bacd691cSlogin self.running.store(false, Ordering::Release); 194bacd691cSlogin } 195bacd691cSlogin } 196bacd691cSlogin impl SoftirqVec for DoTimerSoftirq { 197bacd691cSlogin fn run(&self) { 198840045afSLoGin if !self.set_run() { 199bacd691cSlogin return; 200bacd691cSlogin } 201bacd691cSlogin // 最多只处理TIMER_RUN_CYCLE_THRESHOLD个计时器 202bacd691cSlogin for _ in 0..TIMER_RUN_CYCLE_THRESHOLD { 203bacd691cSlogin // kdebug!("DoTimerSoftirq run"); 2040d6cf65aSLoGin let timer_list = TIMER_LIST.try_lock_irqsave(); 205cde5492fSlogin if timer_list.is_err() { 206cde5492fSlogin continue; 207cde5492fSlogin } 208cde5492fSlogin let mut timer_list = timer_list.unwrap(); 209bacd691cSlogin 210bacd691cSlogin if timer_list.is_empty() { 211bacd691cSlogin break; 212bacd691cSlogin } 213bacd691cSlogin 214b8ed3825SDonkey Kane let (front_jiffies, timer_list_front) = timer_list.first().unwrap().clone(); 215cde5492fSlogin // kdebug!("to lock timer_list_front"); 216b8ed3825SDonkey Kane 217b8ed3825SDonkey Kane if front_jiffies >= TIMER_JIFFIES.load(Ordering::SeqCst) { 218cde5492fSlogin break; 219cde5492fSlogin } 220b8ed3825SDonkey Kane timer_list.remove(0); 221cde5492fSlogin drop(timer_list); 222cde5492fSlogin timer_list_front.run(); 223bacd691cSlogin } 224bacd691cSlogin 225bacd691cSlogin self.clear_run(); 226bacd691cSlogin } 227bacd691cSlogin } 228bacd691cSlogin 2295b59005fSLoGin /// 初始化系统定时器 2305b59005fSLoGin #[inline(never)] 231bacd691cSlogin pub fn timer_init() { 232bacd691cSlogin // FIXME 调用register_trap 233bacd691cSlogin let do_timer_softirq = Arc::new(DoTimerSoftirq::new()); 234bacd691cSlogin softirq_vectors() 235bacd691cSlogin .register_softirq(SoftirqNumber::TIMER, do_timer_softirq) 236bacd691cSlogin .expect("Failed to register timer softirq"); 23740fe15e0SLoGin kinfo!("timer initialized successfully"); 238bacd691cSlogin } 239bacd691cSlogin 240bacd691cSlogin /// 计算接下来n毫秒对应的定时器时间片 241bacd691cSlogin pub fn next_n_ms_timer_jiffies(expire_ms: u64) -> u64 { 242b8ed3825SDonkey Kane return TIMER_JIFFIES.load(Ordering::SeqCst) + expire_ms * 1000000 / NSEC_PER_JIFFY as u64; 243bacd691cSlogin } 244bacd691cSlogin /// 计算接下来n微秒对应的定时器时间片 245bacd691cSlogin pub fn next_n_us_timer_jiffies(expire_us: u64) -> u64 { 246b8ed3825SDonkey Kane return TIMER_JIFFIES.load(Ordering::SeqCst) + expire_us * 1000 / NSEC_PER_JIFFY as u64; 247bacd691cSlogin } 248bacd691cSlogin 249bacd691cSlogin /// @brief 让pcb休眠timeout个jiffies 250bacd691cSlogin /// 251bacd691cSlogin /// @param timeout 需要休眠的时间(单位:jiffies) 252bacd691cSlogin /// 253bacd691cSlogin /// @return Ok(i64) 剩余需要休眠的时间(单位:jiffies) 254bacd691cSlogin /// 255bacd691cSlogin /// @return Err(SystemError) 错误码 256bacd691cSlogin pub fn schedule_timeout(mut timeout: i64) -> Result<i64, SystemError> { 257bacd691cSlogin // kdebug!("schedule_timeout"); 258bacd691cSlogin if timeout == MAX_TIMEOUT { 2598cb2e9b3SLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 260be8cdf4bSLoGin ProcessManager::mark_sleep(true).ok(); 2618cb2e9b3SLoGin drop(irq_guard); 262*3959e94dS曾俊 schedule(SchedMode::SM_NONE); 263bacd691cSlogin return Ok(MAX_TIMEOUT); 264bacd691cSlogin } else if timeout < 0 { 265bacd691cSlogin kerror!("timeout can't less than 0"); 266bacd691cSlogin return Err(SystemError::EINVAL); 267bacd691cSlogin } else { 268bacd691cSlogin // 禁用中断,防止在这段期间发生调度,造成死锁 26936fd0130Shoumkh let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 27036fd0130Shoumkh 27136fd0130Shoumkh timeout += TIMER_JIFFIES.load(Ordering::SeqCst) as i64; 2721496ba7bSLoGin let timer = Timer::new( 2731496ba7bSLoGin WakeUpHelper::new(ProcessManager::current_pcb()), 2741496ba7bSLoGin timeout as u64, 2751496ba7bSLoGin ); 2761496ba7bSLoGin ProcessManager::mark_sleep(true).ok(); 277bacd691cSlogin timer.activate(); 27836fd0130Shoumkh 27936fd0130Shoumkh drop(irq_guard); 280bacd691cSlogin 281*3959e94dS曾俊 schedule(SchedMode::SM_NONE); 28236fd0130Shoumkh let time_remaining: i64 = timeout - TIMER_JIFFIES.load(Ordering::SeqCst) as i64; 283bacd691cSlogin if time_remaining >= 0 { 284bacd691cSlogin // 被提前唤醒,返回剩余时间 285bacd691cSlogin return Ok(time_remaining); 286bacd691cSlogin } else { 287bacd691cSlogin return Ok(0); 288bacd691cSlogin } 289bacd691cSlogin } 290bacd691cSlogin } 291bacd691cSlogin 292bacd691cSlogin pub fn timer_get_first_expire() -> Result<u64, SystemError> { 293bacd691cSlogin // FIXME 294bacd691cSlogin // kdebug!("rs_timer_get_first_expire,timer_jif = {:?}", TIMER_JIFFIES); 295bacd691cSlogin for _ in 0..10 { 296be8cdf4bSLoGin match TIMER_LIST.try_lock_irqsave() { 297bacd691cSlogin Ok(timer_list) => { 298bacd691cSlogin // kdebug!("rs_timer_get_first_expire TIMER_LIST lock successfully"); 299bacd691cSlogin if timer_list.is_empty() { 300bacd691cSlogin // kdebug!("timer_list is empty"); 301bacd691cSlogin return Ok(0); 302bacd691cSlogin } else { 303bacd691cSlogin // kdebug!("timer_list not empty"); 304b8ed3825SDonkey Kane return Ok(timer_list.first().unwrap().0); 305bacd691cSlogin } 306bacd691cSlogin } 307bacd691cSlogin // 加锁失败返回啥?? 308bacd691cSlogin Err(_) => continue, 309bacd691cSlogin } 310bacd691cSlogin } 31179a452ceShoumkh return Err(SystemError::EAGAIN_OR_EWOULDBLOCK); 312bacd691cSlogin } 313bacd691cSlogin 314be8cdf4bSLoGin /// 更新系统时间片 3150d6cf65aSLoGin pub fn update_timer_jiffies(add_jiffies: u64, time_us: i64) -> u64 { 31636fd0130Shoumkh let prev = TIMER_JIFFIES.fetch_add(add_jiffies, Ordering::SeqCst); 31736fd0130Shoumkh compiler_fence(Ordering::SeqCst); 3180d6cf65aSLoGin update_wall_time(time_us); 31936fd0130Shoumkh 32036fd0130Shoumkh compiler_fence(Ordering::SeqCst); 32136fd0130Shoumkh return prev + add_jiffies; 322bacd691cSlogin } 32336fd0130Shoumkh 324bacd691cSlogin pub fn clock() -> u64 { 32536fd0130Shoumkh return TIMER_JIFFIES.load(Ordering::SeqCst); 326bacd691cSlogin } 327bacd691cSlogin 328bacd691cSlogin // ====== 以下为给C提供的接口 ====== 329bacd691cSlogin 330bacd691cSlogin #[no_mangle] 331bacd691cSlogin pub extern "C" fn rs_timer_init() { 332bacd691cSlogin timer_init(); 333bacd691cSlogin } 334