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 collections::LinkedList, 10 sync::{Arc, Weak}, 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::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<LinkedList<Arc<Timer>>> = SpinLock::new(LinkedList::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 100 timer_list.push_back(inner_guard.self_ref.upgrade().unwrap()); 101 102 drop(inner_guard); 103 drop(timer_list); 104 compiler_fence(Ordering::SeqCst); 105 106 return; 107 } 108 let mut split_pos: usize = 0; 109 for (pos, elt) in timer_list.iter().enumerate() { 110 if elt.inner().expire_jiffies > inner_guard.expire_jiffies { 111 split_pos = pos; 112 break; 113 } 114 } 115 let mut temp_list: LinkedList<Arc<Timer>> = timer_list.split_off(split_pos); 116 timer_list.push_back(inner_guard.self_ref.upgrade().unwrap()); 117 timer_list.append(&mut temp_list); 118 drop(inner_guard); 119 drop(timer_list); 120 } 121 122 #[inline] 123 fn run(&self) { 124 let mut timer = self.inner(); 125 timer.triggered = true; 126 let func = timer.timer_func.take(); 127 drop(timer); 128 let r = func.map(|mut f| f.run()).unwrap_or(Ok(())); 129 if unlikely(r.is_err()) { 130 kerror!( 131 "Failed to run timer function: {self:?} {:?}", 132 r.as_ref().err().unwrap() 133 ); 134 } 135 } 136 137 /// ## 判断定时器是否已经触发 138 pub fn timeout(&self) -> bool { 139 self.inner().triggered 140 } 141 142 /// ## 取消定时器任务 143 pub fn cancel(&self) -> bool { 144 let this_arc = self.inner().self_ref.upgrade().unwrap(); 145 TIMER_LIST 146 .lock_irqsave() 147 .extract_if(|x| Arc::ptr_eq(&this_arc, x)) 148 .for_each(|p| drop(p)); 149 true 150 } 151 } 152 153 /// 定时器类型 154 #[derive(Debug)] 155 pub struct InnerTimer { 156 /// 定时器结束时刻 157 pub expire_jiffies: u64, 158 /// 定时器需要执行的函数结构体 159 pub timer_func: Option<Box<dyn TimerFunction>>, 160 /// self_ref 161 self_ref: Weak<Timer>, 162 /// 判断该计时器是否触发 163 triggered: bool, 164 } 165 166 #[derive(Debug)] 167 pub struct DoTimerSoftirq { 168 running: AtomicBool, 169 } 170 171 impl DoTimerSoftirq { 172 pub fn new() -> Self { 173 return DoTimerSoftirq { 174 running: AtomicBool::new(false), 175 }; 176 } 177 178 fn set_run(&self) -> bool { 179 let x = self 180 .running 181 .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed); 182 if x.is_ok() { 183 return true; 184 } else { 185 return false; 186 } 187 } 188 189 fn clear_run(&self) { 190 self.running.store(false, Ordering::Release); 191 } 192 } 193 impl SoftirqVec for DoTimerSoftirq { 194 fn run(&self) { 195 if self.set_run() == false { 196 return; 197 } 198 // 最多只处理TIMER_RUN_CYCLE_THRESHOLD个计时器 199 for _ in 0..TIMER_RUN_CYCLE_THRESHOLD { 200 // kdebug!("DoTimerSoftirq run"); 201 let timer_list = TIMER_LIST.try_lock_irqsave(); 202 if timer_list.is_err() { 203 continue; 204 } 205 let mut timer_list = timer_list.unwrap(); 206 207 if timer_list.is_empty() { 208 break; 209 } 210 211 let timer_list_front = timer_list.pop_front().unwrap(); 212 // kdebug!("to lock timer_list_front"); 213 let mut timer_list_front_guard = None; 214 for _ in 0..10 { 215 let x = timer_list_front.inner.try_lock_irqsave(); 216 if x.is_err() { 217 continue; 218 } 219 timer_list_front_guard = Some(x.unwrap()); 220 } 221 if timer_list_front_guard.is_none() { 222 continue; 223 } 224 let timer_list_front_guard = timer_list_front_guard.unwrap(); 225 if timer_list_front_guard.expire_jiffies > TIMER_JIFFIES.load(Ordering::SeqCst) { 226 drop(timer_list_front_guard); 227 timer_list.push_front(timer_list_front); 228 break; 229 } 230 drop(timer_list_front_guard); 231 drop(timer_list); 232 timer_list_front.run(); 233 } 234 235 self.clear_run(); 236 } 237 } 238 239 /// @brief 初始化timer模块 240 pub fn timer_init() { 241 // FIXME 调用register_trap 242 let do_timer_softirq = Arc::new(DoTimerSoftirq::new()); 243 softirq_vectors() 244 .register_softirq(SoftirqNumber::TIMER, do_timer_softirq) 245 .expect("Failed to register timer softirq"); 246 kinfo!("timer initialized successfully"); 247 } 248 249 /// 计算接下来n毫秒对应的定时器时间片 250 pub fn next_n_ms_timer_jiffies(expire_ms: u64) -> u64 { 251 return TIMER_JIFFIES.load(Ordering::SeqCst) + 1000 * (expire_ms); 252 } 253 /// 计算接下来n微秒对应的定时器时间片 254 pub fn next_n_us_timer_jiffies(expire_us: u64) -> u64 { 255 return TIMER_JIFFIES.load(Ordering::SeqCst) + (expire_us); 256 } 257 258 /// @brief 让pcb休眠timeout个jiffies 259 /// 260 /// @param timeout 需要休眠的时间(单位:jiffies) 261 /// 262 /// @return Ok(i64) 剩余需要休眠的时间(单位:jiffies) 263 /// 264 /// @return Err(SystemError) 错误码 265 pub fn schedule_timeout(mut timeout: i64) -> Result<i64, SystemError> { 266 // kdebug!("schedule_timeout"); 267 if timeout == MAX_TIMEOUT { 268 ProcessManager::mark_sleep(true).ok(); 269 sched(); 270 return Ok(MAX_TIMEOUT); 271 } else if timeout < 0 { 272 kerror!("timeout can't less than 0"); 273 return Err(SystemError::EINVAL); 274 } else { 275 // 禁用中断,防止在这段期间发生调度,造成死锁 276 let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 277 278 timeout += TIMER_JIFFIES.load(Ordering::SeqCst) as i64; 279 let timer = Timer::new( 280 WakeUpHelper::new(ProcessManager::current_pcb()), 281 timeout as u64, 282 ); 283 ProcessManager::mark_sleep(true).ok(); 284 timer.activate(); 285 286 drop(irq_guard); 287 288 sched(); 289 let time_remaining: i64 = timeout - TIMER_JIFFIES.load(Ordering::SeqCst) as i64; 290 if time_remaining >= 0 { 291 // 被提前唤醒,返回剩余时间 292 return Ok(time_remaining); 293 } else { 294 return Ok(0); 295 } 296 } 297 } 298 299 pub fn timer_get_first_expire() -> Result<u64, SystemError> { 300 // FIXME 301 // kdebug!("rs_timer_get_first_expire,timer_jif = {:?}", TIMER_JIFFIES); 302 for _ in 0..10 { 303 match TIMER_LIST.try_lock_irqsave() { 304 Ok(timer_list) => { 305 // kdebug!("rs_timer_get_first_expire TIMER_LIST lock successfully"); 306 if timer_list.is_empty() { 307 // kdebug!("timer_list is empty"); 308 return Ok(0); 309 } else { 310 // kdebug!("timer_list not empty"); 311 return Ok(timer_list.front().unwrap().inner().expire_jiffies); 312 } 313 } 314 // 加锁失败返回啥?? 315 Err(_) => continue, 316 } 317 } 318 return Err(SystemError::EAGAIN_OR_EWOULDBLOCK); 319 } 320 321 /// 更新系统时间片 322 /// 323 /// todo: 这里的实现有问题,貌似把HPET的500us当成了500个jiffies,然后update_wall_time()里面也硬编码了这个500us 324 pub fn update_timer_jiffies(add_jiffies: u64, time_us: i64) -> u64 { 325 let prev = TIMER_JIFFIES.fetch_add(add_jiffies, Ordering::SeqCst); 326 compiler_fence(Ordering::SeqCst); 327 update_wall_time(time_us); 328 329 compiler_fence(Ordering::SeqCst); 330 return prev + add_jiffies; 331 } 332 333 pub fn clock() -> u64 { 334 return TIMER_JIFFIES.load(Ordering::SeqCst); 335 } 336 337 // ====== 以下为给C提供的接口 ====== 338 339 #[no_mangle] 340 pub extern "C" fn rs_timer_init() { 341 timer_init(); 342 } 343