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 {
run(&mut self) -> Result<(), SystemError>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 {
new(pcb: Arc<ProcessControlBlock>) -> Box<WakeUpHelper>47 pub fn new(pcb: Arc<ProcessControlBlock>) -> Box<WakeUpHelper> {
48 return Box::new(WakeUpHelper { pcb });
49 }
50 }
51
52 impl TimerFunction for WakeUpHelper {
run(&mut self) -> Result<(), SystemError>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 定时器结构体
new(timer_func: Box<dyn TimerFunction>, expire_jiffies: u64) -> Arc<Self>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
inner(&self) -> SpinLockGuard<InnerTimer>87 pub fn inner(&self) -> SpinLockGuard<InnerTimer> {
88 return self.inner.lock_irqsave();
89 }
90
91 /// @brief 将定时器插入到定时器链表中
activate(&self)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]
run(&self)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 /// ## 判断定时器是否已经触发
timeout(&self) -> bool138 pub fn timeout(&self) -> bool {
139 self.inner().triggered
140 }
141
142 /// ## 取消定时器任务
cancel(&self) -> bool143 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(drop);
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 {
new() -> Self172 pub fn new() -> Self {
173 return DoTimerSoftirq {
174 running: AtomicBool::new(false),
175 };
176 }
177
set_run(&self) -> bool178 fn set_run(&self) -> bool {
179 let x = self
180 .running
181 .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed);
182 return x.is_ok();
183 }
184
clear_run(&self)185 fn clear_run(&self) {
186 self.running.store(false, Ordering::Release);
187 }
188 }
189 impl SoftirqVec for DoTimerSoftirq {
run(&self)190 fn run(&self) {
191 if !self.set_run() {
192 return;
193 }
194 // 最多只处理TIMER_RUN_CYCLE_THRESHOLD个计时器
195 for _ in 0..TIMER_RUN_CYCLE_THRESHOLD {
196 // kdebug!("DoTimerSoftirq run");
197 let timer_list = TIMER_LIST.try_lock_irqsave();
198 if timer_list.is_err() {
199 continue;
200 }
201 let mut timer_list = timer_list.unwrap();
202
203 if timer_list.is_empty() {
204 break;
205 }
206
207 let timer_list_front = timer_list.pop_front().unwrap();
208 // kdebug!("to lock timer_list_front");
209 let mut timer_list_front_guard = None;
210 for _ in 0..10 {
211 let x = timer_list_front.inner.try_lock_irqsave();
212 if x.is_err() {
213 continue;
214 }
215 timer_list_front_guard = Some(x.unwrap());
216 }
217 if timer_list_front_guard.is_none() {
218 continue;
219 }
220 let timer_list_front_guard = timer_list_front_guard.unwrap();
221 if timer_list_front_guard.expire_jiffies > TIMER_JIFFIES.load(Ordering::SeqCst) {
222 drop(timer_list_front_guard);
223 timer_list.push_front(timer_list_front);
224 break;
225 }
226 drop(timer_list_front_guard);
227 drop(timer_list);
228 timer_list_front.run();
229 }
230
231 self.clear_run();
232 }
233 }
234
235 /// 初始化系统定时器
236 #[inline(never)]
timer_init()237 pub fn timer_init() {
238 // FIXME 调用register_trap
239 let do_timer_softirq = Arc::new(DoTimerSoftirq::new());
240 softirq_vectors()
241 .register_softirq(SoftirqNumber::TIMER, do_timer_softirq)
242 .expect("Failed to register timer softirq");
243 kinfo!("timer initialized successfully");
244 }
245
246 /// 计算接下来n毫秒对应的定时器时间片
next_n_ms_timer_jiffies(expire_ms: u64) -> u64247 pub fn next_n_ms_timer_jiffies(expire_ms: u64) -> u64 {
248 return TIMER_JIFFIES.load(Ordering::SeqCst) + 1000 * (expire_ms);
249 }
250 /// 计算接下来n微秒对应的定时器时间片
next_n_us_timer_jiffies(expire_us: u64) -> u64251 pub fn next_n_us_timer_jiffies(expire_us: u64) -> u64 {
252 return TIMER_JIFFIES.load(Ordering::SeqCst) + (expire_us);
253 }
254
255 /// @brief 让pcb休眠timeout个jiffies
256 ///
257 /// @param timeout 需要休眠的时间(单位:jiffies)
258 ///
259 /// @return Ok(i64) 剩余需要休眠的时间(单位:jiffies)
260 ///
261 /// @return Err(SystemError) 错误码
schedule_timeout(mut timeout: i64) -> Result<i64, SystemError>262 pub fn schedule_timeout(mut timeout: i64) -> Result<i64, SystemError> {
263 // kdebug!("schedule_timeout");
264 if timeout == MAX_TIMEOUT {
265 ProcessManager::mark_sleep(true).ok();
266 sched();
267 return Ok(MAX_TIMEOUT);
268 } else if timeout < 0 {
269 kerror!("timeout can't less than 0");
270 return Err(SystemError::EINVAL);
271 } else {
272 // 禁用中断,防止在这段期间发生调度,造成死锁
273 let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
274
275 timeout += TIMER_JIFFIES.load(Ordering::SeqCst) as i64;
276 let timer = Timer::new(
277 WakeUpHelper::new(ProcessManager::current_pcb()),
278 timeout as u64,
279 );
280 ProcessManager::mark_sleep(true).ok();
281 timer.activate();
282
283 drop(irq_guard);
284
285 sched();
286 let time_remaining: i64 = timeout - TIMER_JIFFIES.load(Ordering::SeqCst) as i64;
287 if time_remaining >= 0 {
288 // 被提前唤醒,返回剩余时间
289 return Ok(time_remaining);
290 } else {
291 return Ok(0);
292 }
293 }
294 }
295
timer_get_first_expire() -> Result<u64, SystemError>296 pub fn timer_get_first_expire() -> Result<u64, SystemError> {
297 // FIXME
298 // kdebug!("rs_timer_get_first_expire,timer_jif = {:?}", TIMER_JIFFIES);
299 for _ in 0..10 {
300 match TIMER_LIST.try_lock_irqsave() {
301 Ok(timer_list) => {
302 // kdebug!("rs_timer_get_first_expire TIMER_LIST lock successfully");
303 if timer_list.is_empty() {
304 // kdebug!("timer_list is empty");
305 return Ok(0);
306 } else {
307 // kdebug!("timer_list not empty");
308 return Ok(timer_list.front().unwrap().inner().expire_jiffies);
309 }
310 }
311 // 加锁失败返回啥??
312 Err(_) => continue,
313 }
314 }
315 return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
316 }
317
318 /// 更新系统时间片
319 ///
320 /// todo: 这里的实现有问题,貌似把HPET的500us当成了500个jiffies,然后update_wall_time()里面也硬编码了这个500us
update_timer_jiffies(add_jiffies: u64, time_us: i64) -> u64321 pub fn update_timer_jiffies(add_jiffies: u64, time_us: i64) -> u64 {
322 let prev = TIMER_JIFFIES.fetch_add(add_jiffies, Ordering::SeqCst);
323 compiler_fence(Ordering::SeqCst);
324 update_wall_time(time_us);
325
326 compiler_fence(Ordering::SeqCst);
327 return prev + add_jiffies;
328 }
329
clock() -> u64330 pub fn clock() -> u64 {
331 return TIMER_JIFFIES.load(Ordering::SeqCst);
332 }
333
334 // ====== 以下为给C提供的接口 ======
335
336 #[no_mangle]
rs_timer_init()337 pub extern "C" fn rs_timer_init() {
338 timer_init();
339 }
340