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