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