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