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