xref: /DragonOS/kernel/src/time/clocksource.rs (revision 471d65cf158c9bf741c21f5d0ab92efe7bf1c3d4)
1 use core::{
2     fmt::Debug,
3     sync::atomic::{AtomicBool, Ordering},
4 };
5 
6 use alloc::{
7     boxed::Box,
8     collections::LinkedList,
9     string::{String, ToString},
10     sync::Arc,
11     vec::Vec,
12 };
13 use lazy_static::__Deref;
14 use system_error::SystemError;
15 use unified_init::macros::unified_init;
16 
17 use crate::{
18     arch::CurrentIrqArch,
19     exception::InterruptArch,
20     init::initcall::INITCALL_LATE,
21     kdebug, kinfo,
22     libs::spinlock::SpinLock,
23     process::{
24         kthread::{KernelThreadClosure, KernelThreadMechanism},
25         ProcessControlBlock, ProcessManager,
26     },
27     sched::{schedule, SchedMode},
28 };
29 
30 use super::{
31     jiffies::clocksource_default_clock,
32     timer::{clock, Timer, TimerFunction},
33     NSEC_PER_SEC,
34 };
35 
36 lazy_static! {
37     /// linked list with the registered clocksources
38     pub static ref CLOCKSOURCE_LIST: SpinLock<LinkedList<Arc<dyn Clocksource>>> =
39         SpinLock::new(LinkedList::new());
40     /// 被监视中的时钟源
41     pub static ref WATCHDOG_LIST: SpinLock<LinkedList<Arc<dyn Clocksource>>> =
42         SpinLock::new(LinkedList::new());
43 
44     pub static ref CLOCKSOUCE_WATCHDOG:SpinLock<ClocksouceWatchdog>  = SpinLock::new(ClocksouceWatchdog::new());
45 
46     pub static ref OVERRIDE_NAME: SpinLock<String> = SpinLock::new(String::from(""));
47 
48 
49 }
50 
51 static mut WATCHDOG_KTHREAD: Option<Arc<ProcessControlBlock>> = None;
52 
53 /// 正在被使用时钟源
54 pub static CUR_CLOCKSOURCE: SpinLock<Option<Arc<dyn Clocksource>>> = SpinLock::new(None);
55 /// 是否完成加载
56 pub static mut FINISHED_BOOTING: AtomicBool = AtomicBool::new(false);
57 
58 /// Interval: 0.5sec Threshold: 0.0625s
59 /// 系统节拍率
60 pub const HZ: u64 = 250;
61 /// watchdog检查间隔
62 pub const WATCHDOG_INTERVAL: u64 = HZ >> 1;
63 /// 最大能接受的误差大小
64 pub const WATCHDOG_THRESHOLD: u32 = NSEC_PER_SEC >> 4;
65 
66 // 时钟周期数
67 #[derive(Debug, Clone, Copy)]
68 pub struct CycleNum(u64);
69 
70 #[allow(dead_code)]
71 impl CycleNum {
72     #[inline(always)]
73     pub const fn new(cycle: u64) -> Self {
74         Self(cycle)
75     }
76     #[inline(always)]
77     pub const fn data(&self) -> u64 {
78         self.0
79     }
80     #[inline(always)]
81     #[allow(dead_code)]
82     pub fn add(&self, other: CycleNum) -> CycleNum {
83         CycleNum(self.data() + other.data())
84     }
85     #[inline(always)]
86     pub fn div(&self, other: CycleNum) -> CycleNum {
87         CycleNum(self.data() - other.data())
88     }
89 }
90 
91 bitflags! {
92 
93     #[derive(Default)]
94     pub struct ClocksourceMask: u64 {
95     }
96     /// 时钟状态标记
97     #[derive(Default)]
98     pub struct ClocksourceFlags: u64 {
99         /// 表示时钟设备是连续的
100         const CLOCK_SOURCE_IS_CONTINUOUS = 0x01;
101         /// 表示该时钟源需要经过watchdog检查
102         const CLOCK_SOURCE_MUST_VERIFY = 0x02;
103         /// 表示该时钟源是watchdog
104         const CLOCK_SOURCE_WATCHDOG = 0x10;
105         /// 表示该时钟源是高分辨率的
106         const CLOCK_SOURCE_VALID_FOR_HRES = 0x20;
107         /// 表示该时钟源误差过大
108         const CLOCK_SOURCE_UNSTABLE = 0x40;
109     }
110 }
111 impl From<u64> for ClocksourceMask {
112     fn from(value: u64) -> Self {
113         if value < 64 {
114             return Self::from_bits_truncate((1 << value) - 1);
115         }
116         return Self::from_bits_truncate(u64::MAX);
117     }
118 }
119 impl ClocksourceMask {
120     pub fn new(b: u64) -> Self {
121         Self { bits: b }
122     }
123 }
124 impl ClocksourceFlags {
125     pub fn new(b: u64) -> Self {
126         Self { bits: b }
127     }
128 }
129 
130 #[derive(Debug)]
131 pub struct ClocksouceWatchdog {
132     /// 监视器
133     watchdog: Option<Arc<dyn Clocksource>>,
134     /// 检查器是否在工作的标志
135     is_running: bool,
136     /// 上一次检查的时刻
137     last_check: CycleNum,
138     /// 定时监视器的过期时间
139     timer_expires: u64,
140 }
141 impl ClocksouceWatchdog {
142     pub fn new() -> Self {
143         Self {
144             watchdog: None,
145             is_running: false,
146             last_check: CycleNum(0),
147             timer_expires: 0,
148         }
149     }
150 
151     /// 获取watchdog
152     fn get_watchdog(&mut self) -> &mut Option<Arc<dyn Clocksource>> {
153         &mut self.watchdog
154     }
155 
156     /// 启用检查器
157     pub fn clocksource_start_watchdog(&mut self) {
158         // 如果watchdog未被设置或者已经启用了就退出
159         let watchdog_list = WATCHDOG_LIST.lock_irqsave();
160         if self.is_running || self.watchdog.is_none() || watchdog_list.is_empty() {
161             return;
162         }
163         // 生成一个定时器
164         let wd_timer_func: Box<WatchdogTimerFunc> = Box::new(WatchdogTimerFunc {});
165         self.timer_expires += clock() + WATCHDOG_INTERVAL;
166         self.last_check = self.watchdog.as_ref().unwrap().clone().read();
167         let wd_timer = Timer::new(wd_timer_func, self.timer_expires);
168         wd_timer.activate();
169         self.is_running = true;
170     }
171 
172     /// 停止检查器
173     /// list_len WATCHDOG_LIST长度
174     pub fn clocksource_stop_watchdog(&mut self, list_len: usize) {
175         if !self.is_running || (self.watchdog.is_some() && list_len != 0) {
176             return;
177         }
178         // TODO 当实现了周期性的定时器后 需要将监视用的定时器删除
179         self.is_running = false;
180     }
181 }
182 
183 /// 定时检查器
184 #[derive(Debug)]
185 pub struct WatchdogTimerFunc;
186 impl TimerFunction for WatchdogTimerFunc {
187     fn run(&mut self) -> Result<(), SystemError> {
188         return clocksource_watchdog();
189     }
190 }
191 
192 /// 时钟源的特性
193 pub trait Clocksource: Send + Sync + Debug {
194     // TODO 返回值类型可能需要改变
195     /// returns a cycle value, passes clocksource as argument
196     fn read(&self) -> CycleNum;
197     /// optional function to enable the clocksource
198     fn enable(&self) -> Result<i32, SystemError> {
199         return Err(SystemError::ENOSYS);
200     }
201     /// optional function to disable the clocksource
202     fn disable(&self) -> Result<(), SystemError> {
203         return Err(SystemError::ENOSYS);
204     }
205     /// vsyscall based read
206     fn vread(&self) -> Result<CycleNum, SystemError> {
207         return Err(SystemError::ENOSYS);
208     }
209     /// suspend function for the clocksource, if necessary
210     fn suspend(&self) -> Result<(), SystemError> {
211         return Err(SystemError::ENOSYS);
212     }
213     /// resume function for the clocksource, if necessary
214     fn resume(&self) -> Result<(), SystemError> {
215         return Err(SystemError::ENOSYS);
216     }
217     // 获取时钟源数据
218     fn clocksource_data(&self) -> ClocksourceData;
219 
220     fn update_clocksource_data(&self, _data: ClocksourceData) -> Result<(), SystemError> {
221         return Err(SystemError::ENOSYS);
222     }
223     // 获取时钟源
224     fn clocksource(&self) -> Arc<dyn Clocksource>;
225 }
226 
227 /// # 实现整数log2的运算
228 ///
229 /// ## 参数
230 ///
231 /// * `x` - 要计算的数字
232 ///
233 /// ## 返回值
234 ///
235 /// * `u32` - 返回\log_2(x)的值
236 fn log2(x: u32) -> u32 {
237     let mut result = 0;
238     let mut x = x;
239 
240     if x >= 1 << 16 {
241         x >>= 16;
242         result |= 16;
243     }
244     if x >= 1 << 8 {
245         x >>= 8;
246         result |= 8;
247     }
248     if x >= 1 << 4 {
249         x >>= 4;
250         result |= 4;
251     }
252     if x >= 1 << 2 {
253         x >>= 2;
254         result |= 2;
255     }
256     if x >= 1 << 1 {
257         result |= 1;
258     }
259 
260     result
261 }
262 
263 impl dyn Clocksource {
264     /// # 计算时钟源能记录的最大时间跨度
265     pub fn clocksource_max_deferment(&self) -> u64 {
266         let cs_data_guard = self.clocksource_data();
267 
268         let mut max_cycles: u64;
269         max_cycles = (1 << (63 - (log2(cs_data_guard.mult) + 1))) as u64;
270         max_cycles = max_cycles.min(cs_data_guard.mask.bits);
271         let max_nsecs = clocksource_cyc2ns(
272             CycleNum(max_cycles),
273             cs_data_guard.mult,
274             cs_data_guard.shift,
275         );
276         return max_nsecs - (max_nsecs >> 5);
277     }
278 
279     /// # 注册时钟源
280     ///
281     /// ## 返回值
282     ///
283     /// * `Ok(0)` - 时钟源注册成功。
284     /// * `Err(SystemError)` - 时钟源注册失败。
285     pub fn register(&self) -> Result<i32, SystemError> {
286         let ns = self.clocksource_max_deferment();
287         let mut cs_data = self.clocksource_data();
288         cs_data.max_idle_ns = ns as u32;
289         self.update_clocksource_data(cs_data)?;
290         // 将时钟源加入到时钟源队列中
291         self.clocksource_enqueue();
292         // 将时钟源加入到监视队列中
293         self.clocksource_enqueue_watchdog()
294             .expect("register: failed to enqueue watchdog list");
295         // 选择一个最好的时钟源
296         clocksource_select();
297         kdebug!("clocksource_register successfully");
298         return Ok(0);
299     }
300 
301     /// # 将时钟源插入时钟源队列
302     pub fn clocksource_enqueue(&self) {
303         // 根据rating由大到小排序
304         let cs_data = self.clocksource_data();
305         let mut list_guard = CLOCKSOURCE_LIST.lock();
306         let mut spilt_pos: usize = 0;
307         for (pos, ele) in list_guard.iter().enumerate() {
308             if ele.clocksource_data().rating < cs_data.rating {
309                 spilt_pos = pos;
310                 break;
311             }
312         }
313         let mut temp_list = list_guard.split_off(spilt_pos);
314         let cs = self.clocksource();
315         list_guard.push_back(cs);
316         list_guard.append(&mut temp_list);
317         // kdebug!(
318         //     "CLOCKSOURCE_LIST len = {:?},clocksource_enqueue sccessfully",
319         //     list_guard.len()
320         // );
321     }
322 
323     /// # 将时间源插入监控队列
324     ///
325     /// ## 返回值
326     ///
327     /// * `Ok(0)` - 时间源插入监控队列成功
328     /// * `Err(SystemError)` - 时间源插入监控队列失败
329     pub fn clocksource_enqueue_watchdog(&self) -> Result<i32, SystemError> {
330         // BUG 可能需要lock irq
331         let mut cs_data = self.clocksource_data();
332 
333         let cs = self.clocksource();
334         if cs_data
335             .flags
336             .contains(ClocksourceFlags::CLOCK_SOURCE_MUST_VERIFY)
337         {
338             let mut list_guard = WATCHDOG_LIST.lock_irqsave();
339             // cs是被监视的
340             cs_data
341                 .flags
342                 .remove(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG);
343             cs.update_clocksource_data(cs_data)?;
344             list_guard.push_back(cs);
345         } else {
346             // cs是监视器
347             if cs_data
348                 .flags
349                 .contains(ClocksourceFlags::CLOCK_SOURCE_IS_CONTINUOUS)
350             {
351                 // 如果时钟设备是连续的
352                 cs_data
353                     .flags
354                     .insert(ClocksourceFlags::CLOCK_SOURCE_VALID_FOR_HRES);
355                 cs.update_clocksource_data(cs_data.clone())?;
356             }
357 
358             // 将时钟源加入到监控队列中
359             let mut list_guard = WATCHDOG_LIST.lock_irqsave();
360             list_guard.push_back(cs.clone());
361             drop(list_guard);
362 
363             // 对比当前注册的时间源的精度和监视器的精度
364             let mut cs_watchdog = CLOCKSOUCE_WATCHDOG.lock_irqsave();
365             if cs_watchdog.watchdog.is_none()
366                 || cs_data.rating
367                     > cs_watchdog
368                         .watchdog
369                         .clone()
370                         .unwrap()
371                         .clocksource_data()
372                         .rating
373             {
374                 // 当前注册的时间源的精度更高或者没有监视器,替换监视器
375                 cs_watchdog.watchdog.replace(cs);
376                 clocksource_reset_watchdog();
377             }
378 
379             // 启动监视器
380             cs_watchdog.clocksource_start_watchdog();
381         }
382         return Ok(0);
383     }
384 
385     /// # 将时钟源标记为unstable
386     ///
387     /// ## 参数
388     /// * `delta` - 时钟源误差
389     pub fn set_unstable(&self, delta: i64) -> Result<i32, SystemError> {
390         let mut cs_data = self.clocksource_data();
391         // 打印出unstable的时钟源信息
392         kdebug!(
393             "clocksource :{:?} is unstable, its delta is {:?}",
394             cs_data.name,
395             delta
396         );
397         cs_data.flags.remove(
398             ClocksourceFlags::CLOCK_SOURCE_VALID_FOR_HRES | ClocksourceFlags::CLOCK_SOURCE_WATCHDOG,
399         );
400         cs_data
401             .flags
402             .insert(ClocksourceFlags::CLOCK_SOURCE_UNSTABLE);
403         self.update_clocksource_data(cs_data)?;
404 
405         // 启动watchdog线程 进行后续处理
406         if unsafe { FINISHED_BOOTING.load(Ordering::Relaxed) } {
407             // TODO 在实现了工作队列后,将启动线程换成schedule work
408             run_watchdog_kthread();
409         }
410         return Ok(0);
411     }
412 
413     /// # 将时间源从监视链表中弹出
414     fn clocksource_dequeue_watchdog(&self) {
415         let data = self.clocksource_data();
416         let mut locked_watchdog = CLOCKSOUCE_WATCHDOG.lock_irqsave();
417         let watchdog = locked_watchdog
418             .get_watchdog()
419             .clone()
420             .unwrap()
421             .clocksource_data();
422 
423         let mut list = WATCHDOG_LIST.lock_irqsave();
424         let mut size = list.len();
425 
426         let mut del_pos: usize = size;
427         for (pos, ele) in list.iter().enumerate() {
428             let ele_data = ele.clocksource_data();
429             if ele_data.name.eq(&data.name) && ele_data.rating.eq(&data.rating) {
430                 // 记录要删除的时钟源在监视链表中的下标
431                 del_pos = pos;
432             }
433         }
434 
435         if data
436             .flags
437             .contains(ClocksourceFlags::CLOCK_SOURCE_MUST_VERIFY)
438         {
439             // 如果时钟源是需要被检查的,直接删除时钟源
440             if del_pos != size {
441                 let mut temp_list = list.split_off(del_pos);
442                 temp_list.pop_front();
443                 list.append(&mut temp_list);
444             }
445         } else if watchdog.name.eq(&data.name) && watchdog.rating.eq(&data.rating) {
446             // 如果要删除的时钟源是监视器,则需要找到一个新的监视器
447             // TODO 重新设置时钟源
448             // 将链表解锁防止reset中双重加锁 并释放保存的旧的watchdog的数据
449 
450             // 代替了clocksource_reset_watchdog()的功能,将所有时钟源的watchdog标记清除
451             for ele in list.iter() {
452                 ele.clocksource_data()
453                     .flags
454                     .remove(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG);
455             }
456 
457             // 遍历所有时间源,寻找新的监视器
458             let mut clocksource_list = CLOCKSOURCE_LIST.lock();
459             let mut replace_pos: usize = clocksource_list.len();
460             for (pos, ele) in clocksource_list.iter().enumerate() {
461                 let ele_data = ele.clocksource_data();
462 
463                 if ele_data.name.eq(&data.name) && ele_data.rating.eq(&data.rating)
464                     || ele_data
465                         .flags
466                         .contains(ClocksourceFlags::CLOCK_SOURCE_MUST_VERIFY)
467                 {
468                     // 当前时钟源是要被删除的时钟源或没被检查过的时钟源
469                     // 不适合成为监视器
470                     continue;
471                 }
472                 let watchdog = locked_watchdog.get_watchdog().clone();
473                 if watchdog.is_none()
474                     || ele_data.rating > watchdog.unwrap().clocksource_data().rating
475                 {
476                     // 如果watchdog不存在或者当前时钟源的精度高于watchdog的精度,则记录当前时钟源的下标
477                     replace_pos = pos;
478                 }
479             }
480             // 使用刚刚找到的更好的时钟源替换旧的watchdog
481             if replace_pos < clocksource_list.len() {
482                 let mut temp_list = clocksource_list.split_off(replace_pos);
483                 let new_wd = temp_list.front().unwrap().clone();
484                 clocksource_list.append(&mut temp_list);
485                 // 替换watchdog
486                 locked_watchdog.watchdog.replace(new_wd);
487                 // drop(locked_watchdog);
488             }
489             // 删除时钟源
490             if del_pos != size {
491                 let mut temp_list = list.split_off(del_pos);
492                 temp_list.pop_front();
493                 list.append(&mut temp_list);
494             }
495         }
496 
497         // 清除watchdog标记
498         let mut cs_data = self.clocksource_data();
499         cs_data
500             .flags
501             .remove(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG);
502         self.update_clocksource_data(cs_data)
503             .expect("clocksource_dequeue_watchdog: failed to update clocksource data");
504         size = list.len();
505         // 停止当前的watchdog
506         locked_watchdog.clocksource_stop_watchdog(size - 1);
507     }
508 
509     /// # 将时钟源从时钟源链表中弹出
510     fn clocksource_dequeue(&self) {
511         let mut list = CLOCKSOURCE_LIST.lock();
512         let data = self.clocksource_data();
513         let mut del_pos: usize = list.len();
514         for (pos, ele) in list.iter().enumerate() {
515             let ele_data = ele.clocksource_data();
516             if ele_data.name.eq(&data.name) && ele_data.rating.eq(&data.rating) {
517                 // 记录时钟源在链表中的下标
518                 del_pos = pos;
519             }
520         }
521 
522         // 删除时钟源
523         if del_pos != list.len() {
524             let mut temp_list = list.split_off(del_pos);
525             temp_list.pop_front();
526             list.append(&mut temp_list);
527         }
528     }
529 
530     /// # 注销时钟源
531     #[allow(dead_code)]
532     pub fn unregister(&self) {
533         // 将时钟源从监视链表中弹出
534         self.clocksource_dequeue_watchdog();
535         // 将时钟源从时钟源链表中弹出
536         self.clocksource_dequeue();
537         // 检查是否有更好的时钟源
538         clocksource_select();
539     }
540     /// # 修改时钟源的精度
541     ///
542     /// ## 参数
543     ///
544     /// * `rating` - 指定的时钟精度
545     fn clocksource_change_rating(&self, rating: i32) {
546         // 将时钟源从链表中弹出
547         self.clocksource_dequeue();
548         let mut data = self.clocksource_data();
549         // 修改时钟源的精度
550         data.set_rating(rating);
551         self.update_clocksource_data(data)
552             .expect("clocksource_change_rating:updata clocksource failed");
553         // 插入时钟源到时钟源链表中
554         self.clocksource_enqueue();
555         // 检查是否有更好的时钟源
556         clocksource_select();
557     }
558 }
559 
560 #[derive(Debug, Clone)]
561 pub struct ClocksourceData {
562     /// 时钟源名字
563     pub name: String,
564     /// 时钟精度
565     pub rating: i32,
566     pub mask: ClocksourceMask,
567     pub mult: u32,
568     pub shift: u32,
569     pub max_idle_ns: u32,
570     pub flags: ClocksourceFlags,
571     pub watchdog_last: CycleNum,
572 }
573 
574 impl ClocksourceData {
575     #[allow(dead_code)]
576     pub fn new(
577         name: String,
578         rating: i32,
579         mask: ClocksourceMask,
580         mult: u32,
581         shift: u32,
582         max_idle_ns: u32,
583         flags: ClocksourceFlags,
584     ) -> Self {
585         let csd = ClocksourceData {
586             name,
587             rating,
588             mask,
589             mult,
590             shift,
591             max_idle_ns,
592             flags,
593             watchdog_last: CycleNum(0),
594         };
595         return csd;
596     }
597 
598     pub fn set_name(&mut self, name: String) {
599         self.name = name;
600     }
601     pub fn set_rating(&mut self, rating: i32) {
602         self.rating = rating;
603     }
604     pub fn set_mask(&mut self, mask: ClocksourceMask) {
605         self.mask = mask;
606     }
607     pub fn set_mult(&mut self, mult: u32) {
608         self.mult = mult;
609     }
610     pub fn set_shift(&mut self, shift: u32) {
611         self.shift = shift;
612     }
613     pub fn set_max_idle_ns(&mut self, max_idle_ns: u32) {
614         self.max_idle_ns = max_idle_ns;
615     }
616     pub fn set_flags(&mut self, flags: ClocksourceFlags) {
617         self.flags = flags;
618     }
619     #[allow(dead_code)]
620     pub fn remove_flags(&mut self, flags: ClocksourceFlags) {
621         self.flags.remove(flags)
622     }
623     #[allow(dead_code)]
624     pub fn insert_flags(&mut self, flags: ClocksourceFlags) {
625         self.flags.insert(flags)
626     }
627 }
628 
629 ///  converts clocksource cycles to nanoseconds
630 ///
631 pub fn clocksource_cyc2ns(cycles: CycleNum, mult: u32, shift: u32) -> u64 {
632     return (cycles.data() * mult as u64) >> shift;
633 }
634 
635 /// # 重启所有的时间源
636 #[allow(dead_code)]
637 pub fn clocksource_resume() {
638     let list = CLOCKSOURCE_LIST.lock();
639     for ele in list.iter() {
640         let data = ele.clocksource_data();
641         match ele.resume() {
642             Ok(_) => continue,
643             Err(_) => {
644                 kdebug!("clocksource {:?} resume failed", data.name);
645             }
646         }
647     }
648     clocksource_resume_watchdog();
649 }
650 
651 /// # 暂停所有的时间源
652 #[allow(dead_code)]
653 pub fn clocksource_suspend() {
654     let list = CLOCKSOURCE_LIST.lock();
655     for ele in list.iter() {
656         let data = ele.clocksource_data();
657         match ele.suspend() {
658             Ok(_) => continue,
659             Err(_) => {
660                 kdebug!("clocksource {:?} suspend failed", data.name);
661             }
662         }
663     }
664 }
665 
666 /// # 根据watchdog的精度,来检查被监视的时钟源的误差
667 ///
668 /// ## 返回值
669 ///
670 /// * `Ok()` - 检查完成
671 /// * `Err(SystemError)` - 错误码
672 pub fn clocksource_watchdog() -> Result<(), SystemError> {
673     let mut cs_watchdog = CLOCKSOUCE_WATCHDOG.lock_irqsave();
674     // kdebug!("clocksource_watchdog start");
675 
676     // watchdog没有在运行的话直接退出
677     if !cs_watchdog.is_running || cs_watchdog.watchdog.is_none() {
678         // kdebug!("is_running = {:?},watchdog = {:?}", cs_watchdog.is_running, cs_watchdog.watchdog);
679         return Ok(());
680     }
681     let cur_watchdog = cs_watchdog.watchdog.as_ref().unwrap().clone();
682     let cur_wd_data = cur_watchdog.as_ref().clocksource_data();
683     let cur_wd_nowclock = cur_watchdog.as_ref().read().data();
684 
685     let wd_last = cs_watchdog.last_check.data();
686     let wd_dev_nsec = clocksource_cyc2ns(
687         CycleNum((cur_wd_nowclock - wd_last) & cur_wd_data.mask.bits),
688         cur_wd_data.mult,
689         cur_wd_data.shift,
690     );
691     cs_watchdog.last_check = CycleNum(cur_wd_nowclock);
692     drop(cs_watchdog);
693     let watchdog_list = WATCHDOG_LIST.lock_irqsave();
694     for cs in watchdog_list.iter() {
695         let mut cs_data = cs.clocksource_data();
696         // 判断时钟源是否已经被标记为不稳定
697         if cs_data
698             .flags
699             .contains(ClocksourceFlags::CLOCK_SOURCE_UNSTABLE)
700         {
701             // kdebug!("clocksource_watchdog unstable");
702             // 启动watchdog_kthread
703             run_watchdog_kthread();
704             continue;
705         }
706         // 读取时钟源现在的时间
707         let cs_now_clock = cs.read();
708 
709         // 如果时钟源没有被监视,则开始监视他
710         if !cs_data
711             .flags
712             .contains(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG)
713         {
714             // kdebug!("clocksource_watchdog start watch");
715             cs_data
716                 .flags
717                 .insert(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG);
718             // 记录此次检查的时刻
719             cs_data.watchdog_last = cs_now_clock;
720             cs.update_clocksource_data(cs_data.clone())?;
721             continue;
722         }
723         // kdebug!("cs_data.watchdog_last = {:?},cs_now_clock = {:?}", cs_data.watchdog_last, cs_now_clock);
724         // 计算时钟源的误差
725         let cs_dev_nsec = clocksource_cyc2ns(
726             CycleNum(cs_now_clock.div(cs_data.watchdog_last).data() & cs_data.mask.bits),
727             cs_data.mult,
728             cs_data.shift,
729         );
730         // 记录此次检查的时刻
731         cs_data.watchdog_last = cs_now_clock;
732         cs.update_clocksource_data(cs_data.clone())?;
733         if cs_dev_nsec.abs_diff(wd_dev_nsec) > WATCHDOG_THRESHOLD.into() {
734             // kdebug!("set_unstable");
735             // 误差过大,标记为unstable
736             cs.set_unstable((cs_dev_nsec - wd_dev_nsec).try_into().unwrap())?;
737             continue;
738         }
739         // kdebug!("clocksource_watchdog aaa");
740 
741         // 判断是否要切换为高精度模式
742         if !cs_data
743             .flags
744             .contains(ClocksourceFlags::CLOCK_SOURCE_VALID_FOR_HRES)
745             && cs_data
746                 .flags
747                 .contains(ClocksourceFlags::CLOCK_SOURCE_IS_CONTINUOUS)
748             && cur_wd_data
749                 .flags
750                 .contains(ClocksourceFlags::CLOCK_SOURCE_IS_CONTINUOUS)
751         {
752             cs_data
753                 .flags
754                 .insert(ClocksourceFlags::CLOCK_SOURCE_VALID_FOR_HRES);
755             cs.update_clocksource_data(cs_data)?;
756             // TODO 通知tick机制 切换为高精度模式
757         }
758     }
759     create_new_watchdog_timer_function();
760     return Ok(());
761 }
762 
763 fn create_new_watchdog_timer_function() {
764     let mut cs_watchdog = CLOCKSOUCE_WATCHDOG.lock_irqsave();
765 
766     cs_watchdog.timer_expires += WATCHDOG_INTERVAL;
767     //创建定时器执行watchdog
768     let watchdog_func = Box::new(WatchdogTimerFunc {});
769     let watchdog_timer = Timer::new(watchdog_func, cs_watchdog.timer_expires);
770     watchdog_timer.activate();
771 }
772 
773 fn __clocksource_watchdog_kthread() {
774     let mut del_vec: Vec<usize> = Vec::new();
775     let mut del_clocks: Vec<Arc<dyn Clocksource>> = Vec::new();
776     let mut wd_list = WATCHDOG_LIST.lock_irqsave();
777 
778     // 将不稳定的时钟源弹出监视链表
779     for (pos, ele) in wd_list.iter().enumerate() {
780         let data = ele.clocksource_data();
781         if data.flags.contains(ClocksourceFlags::CLOCK_SOURCE_UNSTABLE) {
782             del_vec.push(pos);
783             del_clocks.push(ele.clone());
784         }
785     }
786     for pos in del_vec {
787         let mut temp_list = wd_list.split_off(pos);
788         temp_list.pop_front();
789         wd_list.append(&mut temp_list);
790     }
791 
792     // 检查是否需要停止watchdog
793     CLOCKSOUCE_WATCHDOG
794         .lock_irqsave()
795         .clocksource_stop_watchdog(wd_list.len());
796     drop(wd_list);
797     // 将不稳定的时钟源精度都设置为最低,然后删除unstable标记
798     for clock in del_clocks.iter() {
799         clock.clocksource_change_rating(0);
800         let mut data = clock.clocksource_data();
801         data.watchdog_last = clock.read();
802         kdebug!("kthread: watchdog_last = {:?}", data.watchdog_last);
803         data.flags.remove(ClocksourceFlags::CLOCK_SOURCE_UNSTABLE);
804         clock
805             .update_clocksource_data(data)
806             .expect("clocksource_watchdog_kthread: failed to update clocksource data");
807 
808         // 重新插入监视链表
809         clock
810             .clocksource_enqueue_watchdog()
811             .expect("clocksource_watchdog_kthread: failed to enqueue watchdog list");
812     }
813 }
814 
815 /// # watchdog线程的逻辑,执行unstable的后续操作
816 pub fn clocksource_watchdog_kthread() -> i32 {
817     // return 0;
818     loop {
819         // kdebug!("clocksource_watchdog_kthread start");
820         __clocksource_watchdog_kthread();
821         if KernelThreadMechanism::should_stop(&ProcessManager::current_pcb()) {
822             break;
823         }
824         let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
825         ProcessManager::mark_sleep(true).expect("clocksource_watchdog_kthread:mark sleep failed");
826         drop(irq_guard);
827         schedule(SchedMode::SM_NONE);
828     }
829     return 0;
830 }
831 
832 /// # 清空所有时钟源的watchdog标志位
833 pub fn clocksource_reset_watchdog() {
834     let list_guard = WATCHDOG_LIST.lock_irqsave();
835     for ele in list_guard.iter() {
836         ele.clocksource_data()
837             .flags
838             .remove(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG);
839     }
840 }
841 
842 /// # 重启检查器
843 pub fn clocksource_resume_watchdog() {
844     clocksource_reset_watchdog();
845 }
846 
847 /// # 根据精度选择最优的时钟源,或者接受用户指定的时间源
848 pub fn clocksource_select() {
849     let list_guard = CLOCKSOURCE_LIST.lock();
850     if unsafe { FINISHED_BOOTING.load(Ordering::Relaxed) } || list_guard.is_empty() {
851         return;
852     }
853     let mut best = list_guard.front().unwrap().clone();
854     let override_name = OVERRIDE_NAME.lock();
855     // 判断是否有用户空间指定的时间源
856     for ele in list_guard.iter() {
857         if ele.clocksource_data().name.eq(override_name.deref()) {
858             // TODO 判断是否是高精度模式
859             // 暂时不支持高精度模式
860             // 如果是高精度模式,但是时钟源不支持高精度模式的话,就要退出循环
861             best = ele.clone();
862             break;
863         }
864     }
865     // 对比当前的时钟源和记录到最好的时钟源的精度
866     if CUR_CLOCKSOURCE.lock().as_ref().is_some() {
867         // 当前时钟源不为空
868         let cur_clocksource = CUR_CLOCKSOURCE.lock().as_ref().unwrap().clone();
869         let best_name = &best.clocksource_data().name;
870         if cur_clocksource.clocksource_data().name.ne(best_name) {
871             kinfo!("Switching to the clocksource {:?}\n", best_name);
872             drop(cur_clocksource);
873             CUR_CLOCKSOURCE.lock().replace(best);
874             // TODO 通知timerkeeping 切换了时间源
875         }
876     } else {
877         // 当前时钟源为空
878         CUR_CLOCKSOURCE.lock().replace(best);
879     }
880     kdebug!(" clocksource_select finish");
881 }
882 
883 /// # clocksource模块加载完成
884 pub fn clocksource_boot_finish() {
885     let mut cur_clocksource = CUR_CLOCKSOURCE.lock();
886     cur_clocksource.replace(clocksource_default_clock());
887     unsafe { FINISHED_BOOTING.store(true, Ordering::Relaxed) };
888     // 清除不稳定的时钟源
889     __clocksource_watchdog_kthread();
890     kdebug!("clocksource_boot_finish");
891 }
892 
893 fn run_watchdog_kthread() {
894     if let Some(watchdog_kthread) = unsafe { WATCHDOG_KTHREAD.clone() } {
895         ProcessManager::wakeup(&watchdog_kthread).ok();
896     }
897 }
898 
899 #[unified_init(INITCALL_LATE)]
900 pub fn init_watchdog_kthread() -> Result<(), SystemError> {
901     assert!(CurrentIrqArch::is_irq_enabled());
902     let closure = KernelThreadClosure::StaticEmptyClosure((
903         &(clocksource_watchdog_kthread as fn() -> i32),
904         (),
905     ));
906     let pcb = KernelThreadMechanism::create_and_run(closure, "clocksource watchdog".to_string())
907         .ok_or(SystemError::EPERM)?;
908     unsafe {
909         WATCHDOG_KTHREAD.replace(pcb);
910     }
911 
912     return Ok(());
913 }
914