1*36fd0130Shoumkh use core::{ 2*36fd0130Shoumkh fmt::Debug, 3*36fd0130Shoumkh intrinsics::unlikely, 4*36fd0130Shoumkh sync::atomic::{compiler_fence, AtomicBool, AtomicU64, Ordering}, 5*36fd0130Shoumkh }; 6bacd691cSlogin 7bacd691cSlogin use alloc::{ 8bacd691cSlogin boxed::Box, 9bacd691cSlogin collections::LinkedList, 10bacd691cSlogin sync::{Arc, Weak}, 11bacd691cSlogin }; 12bacd691cSlogin 13bacd691cSlogin use crate::{ 14*36fd0130Shoumkh arch::{asm::current::current_pcb, sched::sched, CurrentIrqArch}, 15*36fd0130Shoumkh exception::{ 16*36fd0130Shoumkh softirq::{softirq_vectors, SoftirqNumber, SoftirqVec}, 17*36fd0130Shoumkh InterruptArch, 18bacd691cSlogin }, 19*36fd0130Shoumkh include::bindings::bindings::{process_control_block, process_wakeup, PROC_RUNNING}, 20bacd691cSlogin kdebug, kerror, 21bacd691cSlogin libs::spinlock::SpinLock, 22bacd691cSlogin syscall::SystemError, 23bacd691cSlogin }; 24bacd691cSlogin 25*36fd0130Shoumkh use super::timekeeping::update_wall_time; 26*36fd0130Shoumkh 27bacd691cSlogin const MAX_TIMEOUT: i64 = i64::MAX; 28bacd691cSlogin const TIMER_RUN_CYCLE_THRESHOLD: usize = 20; 29*36fd0130Shoumkh static TIMER_JIFFIES: AtomicU64 = AtomicU64::new(0); 30bacd691cSlogin 31bacd691cSlogin lazy_static! { 32bacd691cSlogin pub static ref TIMER_LIST: SpinLock<LinkedList<Arc<Timer>>> = SpinLock::new(LinkedList::new()); 33bacd691cSlogin } 34bacd691cSlogin 35bacd691cSlogin /// 定时器要执行的函数的特征 36*36fd0130Shoumkh pub trait TimerFunction: Send + Sync + Debug { 37*36fd0130Shoumkh fn run(&mut self) -> Result<(), SystemError>; 38bacd691cSlogin } 39bacd691cSlogin 40*36fd0130Shoumkh #[derive(Debug)] 41bacd691cSlogin /// WakeUpHelper函数对应的结构体 42bacd691cSlogin pub struct WakeUpHelper { 43bacd691cSlogin pcb: &'static mut process_control_block, 44bacd691cSlogin } 45bacd691cSlogin 46bacd691cSlogin impl WakeUpHelper { 47bacd691cSlogin pub fn new(pcb: &'static mut process_control_block) -> Box<WakeUpHelper> { 48bacd691cSlogin return Box::new(WakeUpHelper { pcb }); 49bacd691cSlogin } 50bacd691cSlogin } 51bacd691cSlogin 52bacd691cSlogin impl TimerFunction for WakeUpHelper { 53*36fd0130Shoumkh fn run(&mut self) -> Result<(), SystemError> { 54bacd691cSlogin unsafe { 55bacd691cSlogin process_wakeup(self.pcb); 56bacd691cSlogin } 57*36fd0130Shoumkh return Ok(()); 58bacd691cSlogin } 59bacd691cSlogin } 60bacd691cSlogin 61*36fd0130Shoumkh #[derive(Debug)] 62bacd691cSlogin pub struct Timer(SpinLock<InnerTimer>); 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> { 73bacd691cSlogin let result: Arc<Timer> = Arc::new(Timer(SpinLock::new(InnerTimer { 74bacd691cSlogin expire_jiffies, 75bacd691cSlogin timer_func, 76bacd691cSlogin self_ref: Weak::default(), 77bacd691cSlogin }))); 78bacd691cSlogin 79bacd691cSlogin result.0.lock().self_ref = Arc::downgrade(&result); 80bacd691cSlogin 81bacd691cSlogin return result; 82bacd691cSlogin } 83bacd691cSlogin 84bacd691cSlogin /// @brief 将定时器插入到定时器链表中 85bacd691cSlogin pub fn activate(&self) { 86bacd691cSlogin let inner_guard = self.0.lock(); 87cde5492fSlogin let timer_list = &mut TIMER_LIST.lock(); 88cde5492fSlogin 89bacd691cSlogin // 链表为空,则直接插入 90bacd691cSlogin if timer_list.is_empty() { 91bacd691cSlogin // FIXME push_timer 92cde5492fSlogin 93bacd691cSlogin timer_list.push_back(inner_guard.self_ref.upgrade().unwrap()); 94cde5492fSlogin 95cde5492fSlogin drop(inner_guard); 96cde5492fSlogin drop(timer_list); 97cde5492fSlogin compiler_fence(Ordering::SeqCst); 98cde5492fSlogin 99bacd691cSlogin return; 100bacd691cSlogin } 101bacd691cSlogin let mut split_pos: usize = 0; 102bacd691cSlogin for (pos, elt) in timer_list.iter().enumerate() { 103bacd691cSlogin if elt.0.lock().expire_jiffies > inner_guard.expire_jiffies { 104bacd691cSlogin split_pos = pos; 105bacd691cSlogin break; 106bacd691cSlogin } 107bacd691cSlogin } 108*36fd0130Shoumkh 109bacd691cSlogin let mut temp_list: LinkedList<Arc<Timer>> = timer_list.split_off(split_pos); 110bacd691cSlogin timer_list.push_back(inner_guard.self_ref.upgrade().unwrap()); 111bacd691cSlogin timer_list.append(&mut temp_list); 112cde5492fSlogin drop(inner_guard); 113cde5492fSlogin drop(timer_list); 114bacd691cSlogin } 115bacd691cSlogin 116bacd691cSlogin #[inline] 117bacd691cSlogin fn run(&self) { 118*36fd0130Shoumkh let r = self.0.lock().timer_func.run(); 119*36fd0130Shoumkh if unlikely(r.is_err()) { 120*36fd0130Shoumkh kerror!( 121*36fd0130Shoumkh "Failed to run timer function: {self:?} {:?}", 122*36fd0130Shoumkh r.err().unwrap() 123*36fd0130Shoumkh ); 124*36fd0130Shoumkh } 125bacd691cSlogin } 126bacd691cSlogin } 127bacd691cSlogin 128bacd691cSlogin /// 定时器类型 129*36fd0130Shoumkh #[derive(Debug)] 130bacd691cSlogin pub struct InnerTimer { 131bacd691cSlogin /// 定时器结束时刻 132bacd691cSlogin pub expire_jiffies: u64, 133bacd691cSlogin /// 定时器需要执行的函数结构体 134bacd691cSlogin pub timer_func: Box<dyn TimerFunction>, 135bacd691cSlogin /// self_ref 136bacd691cSlogin self_ref: Weak<Timer>, 137bacd691cSlogin } 138bacd691cSlogin 139bacd691cSlogin #[derive(Debug)] 140bacd691cSlogin pub struct DoTimerSoftirq { 141bacd691cSlogin running: AtomicBool, 142bacd691cSlogin } 143bacd691cSlogin 144bacd691cSlogin impl DoTimerSoftirq { 145bacd691cSlogin pub fn new() -> Self { 146bacd691cSlogin return DoTimerSoftirq { 147bacd691cSlogin running: AtomicBool::new(false), 148bacd691cSlogin }; 149bacd691cSlogin } 150bacd691cSlogin 151bacd691cSlogin fn set_run(&self) -> bool { 152bacd691cSlogin let x = self 153bacd691cSlogin .running 154bacd691cSlogin .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed); 155bacd691cSlogin if x.is_ok() { 156bacd691cSlogin return true; 157bacd691cSlogin } else { 158bacd691cSlogin return false; 159bacd691cSlogin } 160bacd691cSlogin } 161bacd691cSlogin 162bacd691cSlogin fn clear_run(&self) { 163bacd691cSlogin self.running.store(false, Ordering::Release); 164bacd691cSlogin } 165bacd691cSlogin } 166bacd691cSlogin impl SoftirqVec for DoTimerSoftirq { 167bacd691cSlogin fn run(&self) { 168bacd691cSlogin if self.set_run() == false { 169bacd691cSlogin return; 170bacd691cSlogin } 171bacd691cSlogin // 最多只处理TIMER_RUN_CYCLE_THRESHOLD个计时器 172bacd691cSlogin for _ in 0..TIMER_RUN_CYCLE_THRESHOLD { 173bacd691cSlogin // kdebug!("DoTimerSoftirq run"); 174cde5492fSlogin let timer_list = TIMER_LIST.try_lock(); 175cde5492fSlogin if timer_list.is_err() { 176cde5492fSlogin continue; 177cde5492fSlogin } 178cde5492fSlogin let mut timer_list = timer_list.unwrap(); 179bacd691cSlogin 180bacd691cSlogin if timer_list.is_empty() { 181bacd691cSlogin break; 182bacd691cSlogin } 183bacd691cSlogin 184cde5492fSlogin let timer_list_front = timer_list.pop_front().unwrap(); 185cde5492fSlogin // kdebug!("to lock timer_list_front"); 186cde5492fSlogin let mut timer_list_front_guard = None; 187cde5492fSlogin for _ in 0..10 { 188cde5492fSlogin let x = timer_list_front.0.try_lock(); 189cde5492fSlogin if x.is_err() { 190cde5492fSlogin continue; 191bacd691cSlogin } 192cde5492fSlogin timer_list_front_guard = Some(x.unwrap()); 193cde5492fSlogin } 194cde5492fSlogin if timer_list_front_guard.is_none() { 195cde5492fSlogin continue; 196cde5492fSlogin } 197cde5492fSlogin let timer_list_front_guard = timer_list_front_guard.unwrap(); 198*36fd0130Shoumkh if timer_list_front_guard.expire_jiffies > TIMER_JIFFIES.load(Ordering::SeqCst) { 199cde5492fSlogin drop(timer_list_front_guard); 200cde5492fSlogin timer_list.push_front(timer_list_front); 201cde5492fSlogin break; 202cde5492fSlogin } 203cde5492fSlogin drop(timer_list_front_guard); 204cde5492fSlogin drop(timer_list); 205cde5492fSlogin timer_list_front.run(); 206bacd691cSlogin } 207bacd691cSlogin 208bacd691cSlogin self.clear_run(); 209bacd691cSlogin } 210bacd691cSlogin } 211bacd691cSlogin 212bacd691cSlogin /// @brief 初始化timer模块 213bacd691cSlogin pub fn timer_init() { 214bacd691cSlogin // FIXME 调用register_trap 215bacd691cSlogin let do_timer_softirq = Arc::new(DoTimerSoftirq::new()); 216bacd691cSlogin softirq_vectors() 217bacd691cSlogin .register_softirq(SoftirqNumber::TIMER, do_timer_softirq) 218bacd691cSlogin .expect("Failed to register timer softirq"); 219bacd691cSlogin kdebug!("timer initiated successfully"); 220bacd691cSlogin } 221bacd691cSlogin 222bacd691cSlogin /// 计算接下来n毫秒对应的定时器时间片 223bacd691cSlogin pub fn next_n_ms_timer_jiffies(expire_ms: u64) -> u64 { 224*36fd0130Shoumkh return TIMER_JIFFIES.load(Ordering::SeqCst) + 1000 * (expire_ms); 225bacd691cSlogin } 226bacd691cSlogin /// 计算接下来n微秒对应的定时器时间片 227bacd691cSlogin pub fn next_n_us_timer_jiffies(expire_us: u64) -> u64 { 228*36fd0130Shoumkh return TIMER_JIFFIES.load(Ordering::SeqCst) + (expire_us); 229bacd691cSlogin } 230bacd691cSlogin 231bacd691cSlogin /// @brief 让pcb休眠timeout个jiffies 232bacd691cSlogin /// 233bacd691cSlogin /// @param timeout 需要休眠的时间(单位:jiffies) 234bacd691cSlogin /// 235bacd691cSlogin /// @return Ok(i64) 剩余需要休眠的时间(单位:jiffies) 236bacd691cSlogin /// 237bacd691cSlogin /// @return Err(SystemError) 错误码 238bacd691cSlogin pub fn schedule_timeout(mut timeout: i64) -> Result<i64, SystemError> { 239bacd691cSlogin // kdebug!("schedule_timeout"); 240bacd691cSlogin if timeout == MAX_TIMEOUT { 241bacd691cSlogin sched(); 242bacd691cSlogin return Ok(MAX_TIMEOUT); 243bacd691cSlogin } else if timeout < 0 { 244bacd691cSlogin kerror!("timeout can't less than 0"); 245bacd691cSlogin return Err(SystemError::EINVAL); 246bacd691cSlogin } else { 247bacd691cSlogin // 禁用中断,防止在这段期间发生调度,造成死锁 248*36fd0130Shoumkh let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 249*36fd0130Shoumkh 250*36fd0130Shoumkh timeout += TIMER_JIFFIES.load(Ordering::SeqCst) as i64; 251bacd691cSlogin let timer = Timer::new(WakeUpHelper::new(current_pcb()), timeout as u64); 252bacd691cSlogin timer.activate(); 253bacd691cSlogin current_pcb().state &= (!PROC_RUNNING) as u64; 254*36fd0130Shoumkh 255*36fd0130Shoumkh drop(irq_guard); 256bacd691cSlogin 257bacd691cSlogin sched(); 258*36fd0130Shoumkh let time_remaining: i64 = timeout - TIMER_JIFFIES.load(Ordering::SeqCst) as i64; 259bacd691cSlogin if time_remaining >= 0 { 260bacd691cSlogin // 被提前唤醒,返回剩余时间 261bacd691cSlogin return Ok(time_remaining); 262bacd691cSlogin } else { 263bacd691cSlogin return Ok(0); 264bacd691cSlogin } 265bacd691cSlogin } 266bacd691cSlogin } 267bacd691cSlogin 268bacd691cSlogin pub fn timer_get_first_expire() -> Result<u64, SystemError> { 269bacd691cSlogin // FIXME 270bacd691cSlogin // kdebug!("rs_timer_get_first_expire,timer_jif = {:?}", TIMER_JIFFIES); 271bacd691cSlogin for _ in 0..10 { 272bacd691cSlogin match TIMER_LIST.try_lock() { 273bacd691cSlogin Ok(timer_list) => { 274bacd691cSlogin // kdebug!("rs_timer_get_first_expire TIMER_LIST lock successfully"); 275bacd691cSlogin if timer_list.is_empty() { 276bacd691cSlogin // kdebug!("timer_list is empty"); 277bacd691cSlogin return Ok(0); 278bacd691cSlogin } else { 279bacd691cSlogin // kdebug!("timer_list not empty"); 280bacd691cSlogin return Ok(timer_list.front().unwrap().0.lock().expire_jiffies); 281bacd691cSlogin } 282bacd691cSlogin } 283bacd691cSlogin // 加锁失败返回啥?? 284bacd691cSlogin Err(_) => continue, 285bacd691cSlogin } 286bacd691cSlogin } 28779a452ceShoumkh return Err(SystemError::EAGAIN_OR_EWOULDBLOCK); 288bacd691cSlogin } 289bacd691cSlogin 290bacd691cSlogin pub fn update_timer_jiffies(add_jiffies: u64) -> u64 { 291*36fd0130Shoumkh let prev = TIMER_JIFFIES.fetch_add(add_jiffies, Ordering::SeqCst); 292*36fd0130Shoumkh compiler_fence(Ordering::SeqCst); 293*36fd0130Shoumkh update_wall_time(); 294*36fd0130Shoumkh 295*36fd0130Shoumkh compiler_fence(Ordering::SeqCst); 296*36fd0130Shoumkh return prev + add_jiffies; 297bacd691cSlogin } 298*36fd0130Shoumkh 299bacd691cSlogin pub fn clock() -> u64 { 300*36fd0130Shoumkh return TIMER_JIFFIES.load(Ordering::SeqCst); 301bacd691cSlogin } 302bacd691cSlogin // ====== 重构完成后请删掉extern C ====== 303bacd691cSlogin #[no_mangle] 304bacd691cSlogin pub extern "C" fn rs_clock() -> u64 { 305bacd691cSlogin clock() 306bacd691cSlogin } 307bacd691cSlogin 308bacd691cSlogin // ====== 以下为给C提供的接口 ====== 309bacd691cSlogin #[no_mangle] 310bacd691cSlogin pub extern "C" fn rs_schedule_timeout(timeout: i64) -> i64 { 311bacd691cSlogin match schedule_timeout(timeout) { 312bacd691cSlogin Ok(v) => { 313bacd691cSlogin return v; 314bacd691cSlogin } 315bacd691cSlogin Err(e) => { 316bacd691cSlogin kdebug!("rs_schedule_timeout run failed"); 317bacd691cSlogin return e.to_posix_errno() as i64; 318bacd691cSlogin } 319bacd691cSlogin } 320bacd691cSlogin } 321bacd691cSlogin 322bacd691cSlogin #[no_mangle] 323bacd691cSlogin pub extern "C" fn rs_timer_init() { 324bacd691cSlogin timer_init(); 325bacd691cSlogin } 326bacd691cSlogin 327bacd691cSlogin #[no_mangle] 328bacd691cSlogin pub extern "C" fn rs_timer_next_n_ms_jiffies(expire_ms: u64) -> u64 { 329bacd691cSlogin return next_n_ms_timer_jiffies(expire_ms); 330bacd691cSlogin } 331bacd691cSlogin 332bacd691cSlogin #[no_mangle] 333bacd691cSlogin pub extern "C" fn rs_timer_next_n_us_jiffies(expire_us: u64) -> u64 { 334bacd691cSlogin return next_n_us_timer_jiffies(expire_us); 335bacd691cSlogin } 336bacd691cSlogin 337bacd691cSlogin #[no_mangle] 338bacd691cSlogin pub extern "C" fn rs_timer_get_first_expire() -> i64 { 339bacd691cSlogin match timer_get_first_expire() { 340bacd691cSlogin Ok(v) => return v as i64, 341cde5492fSlogin Err(_) => return 0, 342bacd691cSlogin } 343bacd691cSlogin } 344bacd691cSlogin 345bacd691cSlogin #[no_mangle] 346bacd691cSlogin pub extern "C" fn rs_update_timer_jiffies(add_jiffies: u64) -> u64 { 347bacd691cSlogin return update_timer_jiffies(add_jiffies); 348bacd691cSlogin } 349