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