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