136fd0130Shoumkh use core::{ 236fd0130Shoumkh fmt::Debug, 336fd0130Shoumkh intrinsics::unlikely, 436fd0130Shoumkh sync::atomic::{compiler_fence, AtomicBool, AtomicU64, Ordering}, 5fbd63a30SSMALLC time::Duration, 636fd0130Shoumkh }; 7bacd691cSlogin 8bacd691cSlogin use alloc::{ 9bacd691cSlogin boxed::Box, 10bacd691cSlogin sync::{Arc, Weak}, 11b8ed3825SDonkey Kane vec::Vec, 12bacd691cSlogin }; 1391e9d4abSLoGin use system_error::SystemError; 14bacd691cSlogin 15bacd691cSlogin use crate::{ 16f0c87a89SGnoCiYeH arch::CurrentIrqArch, 1736fd0130Shoumkh exception::{ 1836fd0130Shoumkh softirq::{softirq_vectors, SoftirqNumber, SoftirqVec}, 1936fd0130Shoumkh InterruptArch, 20bacd691cSlogin }, 21be8cdf4bSLoGin kerror, kinfo, 220d6cf65aSLoGin libs::spinlock::{SpinLock, SpinLockGuard}, 231496ba7bSLoGin process::{ProcessControlBlock, ProcessManager}, 24f0c87a89SGnoCiYeH sched::{schedule, SchedMode}, 25bacd691cSlogin }; 26bacd691cSlogin 27b8ed3825SDonkey Kane use super::{jiffies::NSEC_PER_JIFFY, timekeeping::update_wall_time}; 2836fd0130Shoumkh 29bacd691cSlogin const MAX_TIMEOUT: i64 = i64::MAX; 30bacd691cSlogin const TIMER_RUN_CYCLE_THRESHOLD: usize = 20; 3136fd0130Shoumkh static TIMER_JIFFIES: AtomicU64 = AtomicU64::new(0); 32bacd691cSlogin 33bacd691cSlogin lazy_static! { 34b8ed3825SDonkey Kane pub static ref TIMER_LIST: SpinLock<Vec<(u64, Arc<Timer>)>> = SpinLock::new(Vec::new()); 35bacd691cSlogin } 36bacd691cSlogin 37bacd691cSlogin /// 定时器要执行的函数的特征 3836fd0130Shoumkh pub trait TimerFunction: Send + Sync + Debug { 3936fd0130Shoumkh fn run(&mut self) -> Result<(), SystemError>; 40bacd691cSlogin } 41fbd63a30SSMALLC // # Jiffies结构体(注意这是一段时间的jiffies数而不是某一时刻的定时器时间片) 42fbd63a30SSMALLC 43fbd63a30SSMALLC int_like!(Jiffies, u64); 44fbd63a30SSMALLC 45fbd63a30SSMALLC impl Jiffies { 46fbd63a30SSMALLC /// ## 返回接下来的n_jiffies对应的定时器时间片 47fbd63a30SSMALLC pub fn timer_jiffies(&self) -> u64 { 48fbd63a30SSMALLC let result = TIMER_JIFFIES.load(Ordering::SeqCst) + self.data(); 49fbd63a30SSMALLC result 50fbd63a30SSMALLC } 51fbd63a30SSMALLC } 52fbd63a30SSMALLC 53fbd63a30SSMALLC impl From<Jiffies> for Duration { 54fbd63a30SSMALLC /// # Jiffies转Duration 55fbd63a30SSMALLC /// 56fbd63a30SSMALLC /// ## 参数 57fbd63a30SSMALLC /// 58fbd63a30SSMALLC /// jiffies: 一段时间的jiffies数 59fbd63a30SSMALLC /// 60fbd63a30SSMALLC /// ### 返回值 61fbd63a30SSMALLC /// 62fbd63a30SSMALLC /// Duration: 这段时间的Duration形式 63fbd63a30SSMALLC fn from(jiffies: Jiffies) -> Self { 64fbd63a30SSMALLC let ms = jiffies.data() / 1_000_000 * NSEC_PER_JIFFY as u64; 65fbd63a30SSMALLC let result = Duration::from_millis(ms); 66fbd63a30SSMALLC result 67fbd63a30SSMALLC } 68fbd63a30SSMALLC } 69fbd63a30SSMALLC 70fbd63a30SSMALLC impl From<Duration> for Jiffies { 71fbd63a30SSMALLC /// # Duration 转 Jiffies 72fbd63a30SSMALLC /// 73fbd63a30SSMALLC /// ## 参数 74fbd63a30SSMALLC /// 75fbd63a30SSMALLC /// ms: 表示一段时间的Duration类型 76fbd63a30SSMALLC /// 77fbd63a30SSMALLC /// ### 返回值 78fbd63a30SSMALLC /// 79fbd63a30SSMALLC /// Jiffies结构体: 这段时间的Jiffies数 80fbd63a30SSMALLC fn from(ms: Duration) -> Self { 81fbd63a30SSMALLC let jiffies = ms.as_millis() as u64 * 1_000_000 / NSEC_PER_JIFFY as u64; 82fbd63a30SSMALLC let result = Jiffies::new(jiffies); 83fbd63a30SSMALLC result 84fbd63a30SSMALLC } 85fbd63a30SSMALLC } 86bacd691cSlogin 8736fd0130Shoumkh #[derive(Debug)] 88bacd691cSlogin /// WakeUpHelper函数对应的结构体 89bacd691cSlogin pub struct WakeUpHelper { 901496ba7bSLoGin pcb: Arc<ProcessControlBlock>, 91bacd691cSlogin } 92bacd691cSlogin 93bacd691cSlogin impl WakeUpHelper { 941496ba7bSLoGin pub fn new(pcb: Arc<ProcessControlBlock>) -> Box<WakeUpHelper> { 95bacd691cSlogin return Box::new(WakeUpHelper { pcb }); 96bacd691cSlogin } 97bacd691cSlogin } 98bacd691cSlogin 99bacd691cSlogin impl TimerFunction for WakeUpHelper { 10036fd0130Shoumkh fn run(&mut self) -> Result<(), SystemError> { 1011496ba7bSLoGin ProcessManager::wakeup(&self.pcb).ok(); 10236fd0130Shoumkh return Ok(()); 103bacd691cSlogin } 104bacd691cSlogin } 105bacd691cSlogin 10636fd0130Shoumkh #[derive(Debug)] 1070d6cf65aSLoGin pub struct Timer { 1080d6cf65aSLoGin inner: SpinLock<InnerTimer>, 1090d6cf65aSLoGin } 110bacd691cSlogin 111bacd691cSlogin impl Timer { 112bacd691cSlogin /// @brief 创建一个定时器(单位:ms) 113bacd691cSlogin /// 114bacd691cSlogin /// @param timer_func 定时器需要执行的函数对应的结构体 115bacd691cSlogin /// 116bacd691cSlogin /// @param expire_jiffies 定时器结束时刻 117bacd691cSlogin /// 118bacd691cSlogin /// @return 定时器结构体 119bacd691cSlogin pub fn new(timer_func: Box<dyn TimerFunction>, expire_jiffies: u64) -> Arc<Self> { 1200d6cf65aSLoGin let result: Arc<Timer> = Arc::new(Timer { 1210d6cf65aSLoGin inner: SpinLock::new(InnerTimer { 122bacd691cSlogin expire_jiffies, 1230d6cf65aSLoGin timer_func: Some(timer_func), 124bacd691cSlogin self_ref: Weak::default(), 125971462beSGnoCiYeH triggered: false, 1260d6cf65aSLoGin }), 1270d6cf65aSLoGin }); 128bacd691cSlogin 1290d6cf65aSLoGin result.inner.lock().self_ref = Arc::downgrade(&result); 130bacd691cSlogin 131bacd691cSlogin return result; 132bacd691cSlogin } 133bacd691cSlogin 1340d6cf65aSLoGin pub fn inner(&self) -> SpinLockGuard<InnerTimer> { 1350d6cf65aSLoGin return self.inner.lock_irqsave(); 1360d6cf65aSLoGin } 1370d6cf65aSLoGin 138bacd691cSlogin /// @brief 将定时器插入到定时器链表中 139bacd691cSlogin pub fn activate(&self) { 1400d6cf65aSLoGin let mut timer_list = TIMER_LIST.lock_irqsave(); 1410d6cf65aSLoGin let inner_guard = self.inner(); 142cde5492fSlogin 143bacd691cSlogin // 链表为空,则直接插入 144bacd691cSlogin if timer_list.is_empty() { 145bacd691cSlogin // FIXME push_timer 146b8ed3825SDonkey Kane timer_list.push(( 147b8ed3825SDonkey Kane inner_guard.expire_jiffies, 148b8ed3825SDonkey Kane inner_guard.self_ref.upgrade().unwrap(), 149b8ed3825SDonkey Kane )); 150cde5492fSlogin 151cde5492fSlogin drop(inner_guard); 152cde5492fSlogin drop(timer_list); 153cde5492fSlogin compiler_fence(Ordering::SeqCst); 154cde5492fSlogin 155bacd691cSlogin return; 156bacd691cSlogin } 157b8ed3825SDonkey Kane let expire_jiffies = inner_guard.expire_jiffies; 158b8ed3825SDonkey Kane let self_arc = inner_guard.self_ref.upgrade().unwrap(); 159b8ed3825SDonkey Kane drop(inner_guard); 160bacd691cSlogin let mut split_pos: usize = 0; 161bacd691cSlogin for (pos, elt) in timer_list.iter().enumerate() { 162b8ed3825SDonkey Kane if Arc::ptr_eq(&self_arc, &elt.1) { 163b8ed3825SDonkey Kane kwarn!("Timer already in list"); 164b8ed3825SDonkey Kane } 165b8ed3825SDonkey Kane if elt.0 > expire_jiffies { 166bacd691cSlogin split_pos = pos; 167bacd691cSlogin break; 168bacd691cSlogin } 169bacd691cSlogin } 170b8ed3825SDonkey Kane timer_list.insert(split_pos, (expire_jiffies, self_arc)); 171b8ed3825SDonkey Kane 172cde5492fSlogin drop(timer_list); 173bacd691cSlogin } 174bacd691cSlogin 175bacd691cSlogin #[inline] 176bacd691cSlogin fn run(&self) { 1770d6cf65aSLoGin let mut timer = self.inner(); 178971462beSGnoCiYeH timer.triggered = true; 1790d6cf65aSLoGin let func = timer.timer_func.take(); 1800d6cf65aSLoGin drop(timer); 1810d6cf65aSLoGin let r = func.map(|mut f| f.run()).unwrap_or(Ok(())); 18236fd0130Shoumkh if unlikely(r.is_err()) { 18336fd0130Shoumkh kerror!( 18436fd0130Shoumkh "Failed to run timer function: {self:?} {:?}", 1858d72b68dSJomo r.as_ref().err().unwrap() 18636fd0130Shoumkh ); 18736fd0130Shoumkh } 188bacd691cSlogin } 189971462beSGnoCiYeH 190971462beSGnoCiYeH /// ## 判断定时器是否已经触发 191971462beSGnoCiYeH pub fn timeout(&self) -> bool { 1920d6cf65aSLoGin self.inner().triggered 193971462beSGnoCiYeH } 194971462beSGnoCiYeH 195971462beSGnoCiYeH /// ## 取消定时器任务 196971462beSGnoCiYeH pub fn cancel(&self) -> bool { 1970d6cf65aSLoGin let this_arc = self.inner().self_ref.upgrade().unwrap(); 198971462beSGnoCiYeH TIMER_LIST 1990d6cf65aSLoGin .lock_irqsave() 200b8ed3825SDonkey Kane .extract_if(|x| Arc::ptr_eq(&this_arc, &x.1)) 201840045afSLoGin .for_each(drop); 202971462beSGnoCiYeH true 203971462beSGnoCiYeH } 204bacd691cSlogin } 205bacd691cSlogin 206bacd691cSlogin /// 定时器类型 20736fd0130Shoumkh #[derive(Debug)] 208bacd691cSlogin pub struct InnerTimer { 209bacd691cSlogin /// 定时器结束时刻 210bacd691cSlogin pub expire_jiffies: u64, 211bacd691cSlogin /// 定时器需要执行的函数结构体 2120d6cf65aSLoGin pub timer_func: Option<Box<dyn TimerFunction>>, 213bacd691cSlogin /// self_ref 214bacd691cSlogin self_ref: Weak<Timer>, 215971462beSGnoCiYeH /// 判断该计时器是否触发 216971462beSGnoCiYeH triggered: bool, 217bacd691cSlogin } 218bacd691cSlogin 219bacd691cSlogin #[derive(Debug)] 220bacd691cSlogin pub struct DoTimerSoftirq { 221bacd691cSlogin running: AtomicBool, 222bacd691cSlogin } 223bacd691cSlogin 224bacd691cSlogin impl DoTimerSoftirq { 225bacd691cSlogin pub fn new() -> Self { 226bacd691cSlogin return DoTimerSoftirq { 227bacd691cSlogin running: AtomicBool::new(false), 228bacd691cSlogin }; 229bacd691cSlogin } 230bacd691cSlogin 231bacd691cSlogin fn set_run(&self) -> bool { 232bacd691cSlogin let x = self 233bacd691cSlogin .running 234bacd691cSlogin .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed); 235840045afSLoGin return x.is_ok(); 236bacd691cSlogin } 237bacd691cSlogin 238bacd691cSlogin fn clear_run(&self) { 239bacd691cSlogin self.running.store(false, Ordering::Release); 240bacd691cSlogin } 241bacd691cSlogin } 242bacd691cSlogin impl SoftirqVec for DoTimerSoftirq { 243bacd691cSlogin fn run(&self) { 244840045afSLoGin if !self.set_run() { 245bacd691cSlogin return; 246bacd691cSlogin } 247bacd691cSlogin // 最多只处理TIMER_RUN_CYCLE_THRESHOLD个计时器 248bacd691cSlogin for _ in 0..TIMER_RUN_CYCLE_THRESHOLD { 249bacd691cSlogin // kdebug!("DoTimerSoftirq run"); 2500d6cf65aSLoGin let timer_list = TIMER_LIST.try_lock_irqsave(); 251cde5492fSlogin if timer_list.is_err() { 252cde5492fSlogin continue; 253cde5492fSlogin } 254cde5492fSlogin let mut timer_list = timer_list.unwrap(); 255bacd691cSlogin 256bacd691cSlogin if timer_list.is_empty() { 257bacd691cSlogin break; 258bacd691cSlogin } 259bacd691cSlogin 260b8ed3825SDonkey Kane let (front_jiffies, timer_list_front) = timer_list.first().unwrap().clone(); 261cde5492fSlogin // kdebug!("to lock timer_list_front"); 262b8ed3825SDonkey Kane 263b8ed3825SDonkey Kane if front_jiffies >= TIMER_JIFFIES.load(Ordering::SeqCst) { 264cde5492fSlogin break; 265cde5492fSlogin } 266b8ed3825SDonkey Kane timer_list.remove(0); 267cde5492fSlogin drop(timer_list); 268cde5492fSlogin timer_list_front.run(); 269bacd691cSlogin } 270bacd691cSlogin 271bacd691cSlogin self.clear_run(); 272bacd691cSlogin } 273bacd691cSlogin } 274bacd691cSlogin 2755b59005fSLoGin /// 初始化系统定时器 2765b59005fSLoGin #[inline(never)] 277bacd691cSlogin pub fn timer_init() { 278bacd691cSlogin // FIXME 调用register_trap 279bacd691cSlogin let do_timer_softirq = Arc::new(DoTimerSoftirq::new()); 280bacd691cSlogin softirq_vectors() 281bacd691cSlogin .register_softirq(SoftirqNumber::TIMER, do_timer_softirq) 282bacd691cSlogin .expect("Failed to register timer softirq"); 28340fe15e0SLoGin kinfo!("timer initialized successfully"); 284bacd691cSlogin } 285bacd691cSlogin 286bacd691cSlogin /// 计算接下来n毫秒对应的定时器时间片 287bacd691cSlogin pub fn next_n_ms_timer_jiffies(expire_ms: u64) -> u64 { 288b8ed3825SDonkey Kane return TIMER_JIFFIES.load(Ordering::SeqCst) + expire_ms * 1000000 / NSEC_PER_JIFFY as u64; 289bacd691cSlogin } 290bacd691cSlogin /// 计算接下来n微秒对应的定时器时间片 291bacd691cSlogin pub fn next_n_us_timer_jiffies(expire_us: u64) -> u64 { 292b8ed3825SDonkey Kane return TIMER_JIFFIES.load(Ordering::SeqCst) + expire_us * 1000 / NSEC_PER_JIFFY as u64; 293bacd691cSlogin } 294bacd691cSlogin 295bacd691cSlogin /// @brief 让pcb休眠timeout个jiffies 296bacd691cSlogin /// 297bacd691cSlogin /// @param timeout 需要休眠的时间(单位:jiffies) 298bacd691cSlogin /// 299bacd691cSlogin /// @return Ok(i64) 剩余需要休眠的时间(单位:jiffies) 300bacd691cSlogin /// 301bacd691cSlogin /// @return Err(SystemError) 错误码 302bacd691cSlogin pub fn schedule_timeout(mut timeout: i64) -> Result<i64, SystemError> { 303bacd691cSlogin // kdebug!("schedule_timeout"); 304bacd691cSlogin if timeout == MAX_TIMEOUT { 3058cb2e9b3SLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 306be8cdf4bSLoGin ProcessManager::mark_sleep(true).ok(); 3078cb2e9b3SLoGin drop(irq_guard); 3083959e94dS曾俊 schedule(SchedMode::SM_NONE); 309bacd691cSlogin return Ok(MAX_TIMEOUT); 310bacd691cSlogin } else if timeout < 0 { 311bacd691cSlogin kerror!("timeout can't less than 0"); 312bacd691cSlogin return Err(SystemError::EINVAL); 313bacd691cSlogin } else { 314bacd691cSlogin // 禁用中断,防止在这段期间发生调度,造成死锁 31536fd0130Shoumkh let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 31636fd0130Shoumkh 31736fd0130Shoumkh timeout += TIMER_JIFFIES.load(Ordering::SeqCst) as i64; 3181496ba7bSLoGin let timer = Timer::new( 3191496ba7bSLoGin WakeUpHelper::new(ProcessManager::current_pcb()), 3201496ba7bSLoGin timeout as u64, 3211496ba7bSLoGin ); 3221496ba7bSLoGin ProcessManager::mark_sleep(true).ok(); 323bacd691cSlogin timer.activate(); 32436fd0130Shoumkh 32536fd0130Shoumkh drop(irq_guard); 326bacd691cSlogin 3273959e94dS曾俊 schedule(SchedMode::SM_NONE); 32836fd0130Shoumkh let time_remaining: i64 = timeout - TIMER_JIFFIES.load(Ordering::SeqCst) as i64; 329bacd691cSlogin if time_remaining >= 0 { 330bacd691cSlogin // 被提前唤醒,返回剩余时间 331bacd691cSlogin return Ok(time_remaining); 332bacd691cSlogin } else { 333bacd691cSlogin return Ok(0); 334bacd691cSlogin } 335bacd691cSlogin } 336bacd691cSlogin } 337bacd691cSlogin 338bacd691cSlogin pub fn timer_get_first_expire() -> Result<u64, SystemError> { 339bacd691cSlogin // FIXME 340bacd691cSlogin // kdebug!("rs_timer_get_first_expire,timer_jif = {:?}", TIMER_JIFFIES); 341bacd691cSlogin for _ in 0..10 { 342be8cdf4bSLoGin match TIMER_LIST.try_lock_irqsave() { 343bacd691cSlogin Ok(timer_list) => { 344bacd691cSlogin // kdebug!("rs_timer_get_first_expire TIMER_LIST lock successfully"); 345bacd691cSlogin if timer_list.is_empty() { 346bacd691cSlogin // kdebug!("timer_list is empty"); 347bacd691cSlogin return Ok(0); 348bacd691cSlogin } else { 349bacd691cSlogin // kdebug!("timer_list not empty"); 350b8ed3825SDonkey Kane return Ok(timer_list.first().unwrap().0); 351bacd691cSlogin } 352bacd691cSlogin } 353bacd691cSlogin // 加锁失败返回啥?? 354bacd691cSlogin Err(_) => continue, 355bacd691cSlogin } 356bacd691cSlogin } 35779a452ceShoumkh return Err(SystemError::EAGAIN_OR_EWOULDBLOCK); 358bacd691cSlogin } 359bacd691cSlogin 360*0722a06aSLoGin /// 检查是否需要触发定时器软中断,如果需要则触发 361*0722a06aSLoGin pub fn try_raise_timer_softirq() { 362*0722a06aSLoGin if let Ok(first_expire) = timer_get_first_expire() { 363*0722a06aSLoGin if first_expire <= clock() { 364*0722a06aSLoGin softirq_vectors().raise_softirq(SoftirqNumber::TIMER); 365*0722a06aSLoGin } 366*0722a06aSLoGin } 367*0722a06aSLoGin } 368*0722a06aSLoGin 369be8cdf4bSLoGin /// 更新系统时间片 3700d6cf65aSLoGin pub fn update_timer_jiffies(add_jiffies: u64, time_us: i64) -> u64 { 37136fd0130Shoumkh let prev = TIMER_JIFFIES.fetch_add(add_jiffies, Ordering::SeqCst); 37236fd0130Shoumkh compiler_fence(Ordering::SeqCst); 3730d6cf65aSLoGin update_wall_time(time_us); 37436fd0130Shoumkh 37536fd0130Shoumkh compiler_fence(Ordering::SeqCst); 37636fd0130Shoumkh return prev + add_jiffies; 377bacd691cSlogin } 37836fd0130Shoumkh 379bacd691cSlogin pub fn clock() -> u64 { 38036fd0130Shoumkh return TIMER_JIFFIES.load(Ordering::SeqCst); 381bacd691cSlogin } 382bacd691cSlogin 383bacd691cSlogin // ====== 以下为给C提供的接口 ====== 384bacd691cSlogin 385bacd691cSlogin #[no_mangle] 386bacd691cSlogin pub extern "C" fn rs_timer_init() { 387bacd691cSlogin timer_init(); 388bacd691cSlogin } 389