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