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