xref: /DragonOS/kernel/src/time/clocksource.rs (revision 91e9d4ab55ef960f57a1b6287bc523ca4341f67a)
136fd0130Shoumkh use core::{
236fd0130Shoumkh     ffi::c_void,
336fd0130Shoumkh     fmt::Debug,
436fd0130Shoumkh     sync::atomic::{AtomicBool, Ordering},
536fd0130Shoumkh };
636fd0130Shoumkh 
736fd0130Shoumkh use alloc::{boxed::Box, collections::LinkedList, string::String, sync::Arc, vec::Vec};
836fd0130Shoumkh use lazy_static::__Deref;
9*91e9d4abSLoGin use system_error::SystemError;
1036fd0130Shoumkh 
1136fd0130Shoumkh use crate::{
1236fd0130Shoumkh     include::bindings::bindings::run_watchdog_kthread, kdebug, kinfo, libs::spinlock::SpinLock,
1336fd0130Shoumkh };
1436fd0130Shoumkh 
1536fd0130Shoumkh use super::{
1636fd0130Shoumkh     jiffies::clocksource_default_clock,
1736fd0130Shoumkh     timer::{clock, Timer, TimerFunction},
1836fd0130Shoumkh     NSEC_PER_SEC,
1936fd0130Shoumkh };
2036fd0130Shoumkh 
2136fd0130Shoumkh lazy_static! {
2236fd0130Shoumkh     /// linked list with the registered clocksources
2336fd0130Shoumkh     pub static ref CLOCKSOURCE_LIST: SpinLock<LinkedList<Arc<dyn Clocksource>>> =
2436fd0130Shoumkh         SpinLock::new(LinkedList::new());
2536fd0130Shoumkh     /// 被监视中的时钟源
2636fd0130Shoumkh     pub static ref WATCHDOG_LIST: SpinLock<LinkedList<Arc<dyn Clocksource>>> =
2736fd0130Shoumkh         SpinLock::new(LinkedList::new());
2836fd0130Shoumkh 
2936fd0130Shoumkh     pub static ref CLOCKSOUCE_WATCHDOG:SpinLock<ClocksouceWatchdog>  = SpinLock::new(ClocksouceWatchdog::new());
3036fd0130Shoumkh 
3136fd0130Shoumkh     pub static ref OVERRIDE_NAME: SpinLock<String> = SpinLock::new(String::from(""));
3236fd0130Shoumkh 
3336fd0130Shoumkh 
3436fd0130Shoumkh }
3536fd0130Shoumkh 
3636fd0130Shoumkh /// 正在被使用时钟源
3736fd0130Shoumkh pub static CUR_CLOCKSOURCE: SpinLock<Option<Arc<dyn Clocksource>>> = SpinLock::new(None);
3836fd0130Shoumkh /// 是否完成加载
3936fd0130Shoumkh pub static mut FINISHED_BOOTING: AtomicBool = AtomicBool::new(false);
4036fd0130Shoumkh 
4136fd0130Shoumkh /// Interval: 0.5sec Threshold: 0.0625s
4236fd0130Shoumkh /// 系统节拍率
43be8cdf4bSLoGin pub const HZ: u64 = 250;
4436fd0130Shoumkh /// watchdog检查间隔
4536fd0130Shoumkh pub const WATCHDOG_INTERVAL: u64 = HZ >> 1;
4636fd0130Shoumkh /// 最大能接受的误差大小
4736fd0130Shoumkh pub const WATCHDOG_THRESHOLD: u32 = NSEC_PER_SEC >> 4;
4836fd0130Shoumkh 
4936fd0130Shoumkh // 时钟周期数
5036fd0130Shoumkh #[derive(Debug, Clone, Copy)]
5136fd0130Shoumkh #[repr(transparent)]
5236fd0130Shoumkh pub struct CycleNum(pub u64);
5336fd0130Shoumkh 
5436fd0130Shoumkh #[allow(dead_code)]
5536fd0130Shoumkh impl CycleNum {
5636fd0130Shoumkh     #[inline(always)]
5736fd0130Shoumkh     pub fn new(cycle: u64) -> Self {
5836fd0130Shoumkh         Self(cycle)
5936fd0130Shoumkh     }
6036fd0130Shoumkh     #[inline(always)]
6136fd0130Shoumkh     pub fn data(&self) -> u64 {
6236fd0130Shoumkh         self.0
6336fd0130Shoumkh     }
6436fd0130Shoumkh     #[inline(always)]
6536fd0130Shoumkh     #[allow(dead_code)]
6636fd0130Shoumkh     pub fn add(&self, other: CycleNum) -> CycleNum {
6736fd0130Shoumkh         CycleNum(self.data() + other.data())
6836fd0130Shoumkh     }
6936fd0130Shoumkh     #[inline(always)]
7036fd0130Shoumkh     pub fn div(&self, other: CycleNum) -> CycleNum {
7136fd0130Shoumkh         CycleNum(self.data() - other.data())
7236fd0130Shoumkh     }
7336fd0130Shoumkh }
7436fd0130Shoumkh 
7536fd0130Shoumkh bitflags! {
7636fd0130Shoumkh 
7736fd0130Shoumkh     #[derive(Default)]
7836fd0130Shoumkh     pub struct ClocksourceMask: u64 {
7936fd0130Shoumkh     }
8036fd0130Shoumkh     /// 时钟状态标记
8136fd0130Shoumkh     #[derive(Default)]
8236fd0130Shoumkh     pub struct ClocksourceFlags: u64 {
8336fd0130Shoumkh         /// 表示时钟设备是连续的
8436fd0130Shoumkh         const CLOCK_SOURCE_IS_CONTINUOUS = 0x01;
8536fd0130Shoumkh         /// 表示该时钟源需要经过watchdog检查
8636fd0130Shoumkh         const CLOCK_SOURCE_MUST_VERIFY = 0x02;
8736fd0130Shoumkh         /// 表示该时钟源是watchdog
8836fd0130Shoumkh         const CLOCK_SOURCE_WATCHDOG = 0x10;
8936fd0130Shoumkh         /// 表示该时钟源是高分辨率的
9036fd0130Shoumkh         const CLOCK_SOURCE_VALID_FOR_HRES = 0x20;
9136fd0130Shoumkh         /// 表示该时钟源误差过大
9236fd0130Shoumkh         const CLOCK_SOURCE_UNSTABLE = 0x40;
9336fd0130Shoumkh     }
9436fd0130Shoumkh }
9536fd0130Shoumkh impl From<u64> for ClocksourceMask {
9636fd0130Shoumkh     fn from(value: u64) -> Self {
9736fd0130Shoumkh         if value < 64 {
9836fd0130Shoumkh             return Self::from_bits_truncate((1 << value) - 1);
9936fd0130Shoumkh         }
10036fd0130Shoumkh         return Self::from_bits_truncate(u64::MAX);
10136fd0130Shoumkh     }
10236fd0130Shoumkh }
10336fd0130Shoumkh impl ClocksourceMask {
10436fd0130Shoumkh     pub fn new(b: u64) -> Self {
10536fd0130Shoumkh         Self { bits: b }
10636fd0130Shoumkh     }
10736fd0130Shoumkh }
10836fd0130Shoumkh impl ClocksourceFlags {
10936fd0130Shoumkh     pub fn new(b: u64) -> Self {
11036fd0130Shoumkh         Self { bits: b }
11136fd0130Shoumkh     }
11236fd0130Shoumkh }
11336fd0130Shoumkh 
11436fd0130Shoumkh #[derive(Debug)]
11536fd0130Shoumkh pub struct ClocksouceWatchdog {
11636fd0130Shoumkh     /// 监视器
11736fd0130Shoumkh     watchdog: Option<Arc<dyn Clocksource>>,
11836fd0130Shoumkh     /// 检查器是否在工作的标志
11936fd0130Shoumkh     is_running: bool,
12036fd0130Shoumkh     /// 上一次检查的时刻
12136fd0130Shoumkh     last_check: CycleNum,
12236fd0130Shoumkh     /// 定时监视器的过期时间
12336fd0130Shoumkh     timer_expires: u64,
12436fd0130Shoumkh }
12536fd0130Shoumkh impl ClocksouceWatchdog {
12636fd0130Shoumkh     pub fn new() -> Self {
12736fd0130Shoumkh         Self {
12836fd0130Shoumkh             watchdog: None,
12936fd0130Shoumkh             is_running: false,
13036fd0130Shoumkh             last_check: CycleNum(0),
13136fd0130Shoumkh             timer_expires: 0,
13236fd0130Shoumkh         }
13336fd0130Shoumkh     }
13436fd0130Shoumkh 
13536fd0130Shoumkh     /// 获取watchdog
13636fd0130Shoumkh     fn get_watchdog(&mut self) -> &mut Option<Arc<dyn Clocksource>> {
13736fd0130Shoumkh         &mut self.watchdog
13836fd0130Shoumkh     }
13936fd0130Shoumkh 
14036fd0130Shoumkh     /// 启用检查器
14136fd0130Shoumkh     pub fn clocksource_start_watchdog(&mut self) {
14236fd0130Shoumkh         // 如果watchdog未被设置或者已经启用了就退出
14336fd0130Shoumkh         let watchdog_list = &WATCHDOG_LIST.lock();
14436fd0130Shoumkh         if self.is_running || self.watchdog.is_none() || watchdog_list.is_empty() {
14536fd0130Shoumkh             return;
14636fd0130Shoumkh         }
14736fd0130Shoumkh         // 生成一个定时器
14836fd0130Shoumkh         let wd_timer_func: Box<WatchdogTimerFunc> = Box::new(WatchdogTimerFunc {});
14936fd0130Shoumkh         self.timer_expires += clock() + WATCHDOG_INTERVAL;
15036fd0130Shoumkh         self.last_check = self.watchdog.as_ref().unwrap().clone().read();
15136fd0130Shoumkh         let wd_timer = Timer::new(wd_timer_func, self.timer_expires);
15236fd0130Shoumkh         wd_timer.activate();
15336fd0130Shoumkh         self.is_running = true;
15436fd0130Shoumkh     }
15536fd0130Shoumkh 
15636fd0130Shoumkh     /// 停止检查器
15736fd0130Shoumkh     /// list_len WATCHDOG_LIST长度
15836fd0130Shoumkh     pub fn clocksource_stop_watchdog(&mut self, list_len: usize) {
15936fd0130Shoumkh         if !self.is_running || (self.watchdog.is_some() && list_len != 0) {
16036fd0130Shoumkh             return;
16136fd0130Shoumkh         }
16236fd0130Shoumkh         // TODO 当实现了周期性的定时器后 需要将监视用的定时器删除
16336fd0130Shoumkh         self.is_running = false;
16436fd0130Shoumkh     }
16536fd0130Shoumkh }
16636fd0130Shoumkh 
16736fd0130Shoumkh /// 定时检查器
16836fd0130Shoumkh #[derive(Debug)]
16936fd0130Shoumkh pub struct WatchdogTimerFunc;
17036fd0130Shoumkh impl TimerFunction for WatchdogTimerFunc {
17136fd0130Shoumkh     fn run(&mut self) -> Result<(), SystemError> {
17236fd0130Shoumkh         return clocksource_watchdog();
17336fd0130Shoumkh     }
17436fd0130Shoumkh }
17536fd0130Shoumkh 
17636fd0130Shoumkh /// 时钟源的特性
17736fd0130Shoumkh pub trait Clocksource: Send + Sync + Debug {
17836fd0130Shoumkh     // TODO 返回值类型可能需要改变
17936fd0130Shoumkh     /// returns a cycle value, passes clocksource as argument
18036fd0130Shoumkh     fn read(&self) -> CycleNum;
18136fd0130Shoumkh     /// optional function to enable the clocksource
18236fd0130Shoumkh     fn enable(&self) -> Result<i32, SystemError> {
18336fd0130Shoumkh         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
18436fd0130Shoumkh     }
18536fd0130Shoumkh     /// optional function to disable the clocksource
18636fd0130Shoumkh     fn disable(&self) -> Result<(), SystemError> {
18736fd0130Shoumkh         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
18836fd0130Shoumkh     }
18936fd0130Shoumkh     /// vsyscall based read
19036fd0130Shoumkh     fn vread(&self) -> Result<CycleNum, SystemError> {
19136fd0130Shoumkh         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
19236fd0130Shoumkh     }
19336fd0130Shoumkh     /// suspend function for the clocksource, if necessary
19436fd0130Shoumkh     fn suspend(&self) -> Result<(), SystemError> {
19536fd0130Shoumkh         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
19636fd0130Shoumkh     }
19736fd0130Shoumkh     /// resume function for the clocksource, if necessary
19836fd0130Shoumkh     fn resume(&self) -> Result<(), SystemError> {
19936fd0130Shoumkh         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
20036fd0130Shoumkh     }
20136fd0130Shoumkh     // 获取时钟源数据
20236fd0130Shoumkh     fn clocksource_data(&self) -> ClocksourceData;
20336fd0130Shoumkh 
20436fd0130Shoumkh     fn update_clocksource_data(&self, _data: ClocksourceData) -> Result<(), SystemError> {
20536fd0130Shoumkh         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
20636fd0130Shoumkh     }
20736fd0130Shoumkh     // 获取时钟源
20836fd0130Shoumkh     fn clocksource(&self) -> Arc<dyn Clocksource>;
20936fd0130Shoumkh }
21036fd0130Shoumkh 
21136fd0130Shoumkh /// # 实现整数log2的运算
21236fd0130Shoumkh ///
21336fd0130Shoumkh /// ## 参数
21436fd0130Shoumkh ///
21536fd0130Shoumkh /// * `x` - 要计算的数字
21636fd0130Shoumkh ///
21736fd0130Shoumkh /// ## 返回值
21836fd0130Shoumkh ///
21936fd0130Shoumkh /// * `u32` - 返回\log_2(x)的值
22036fd0130Shoumkh fn log2(x: u32) -> u32 {
22136fd0130Shoumkh     let mut result = 0;
22236fd0130Shoumkh     let mut x = x;
22336fd0130Shoumkh 
22436fd0130Shoumkh     if x >= 1 << 16 {
22536fd0130Shoumkh         x >>= 16;
22636fd0130Shoumkh         result |= 16;
22736fd0130Shoumkh     }
22836fd0130Shoumkh     if x >= 1 << 8 {
22936fd0130Shoumkh         x >>= 8;
23036fd0130Shoumkh         result |= 8;
23136fd0130Shoumkh     }
23236fd0130Shoumkh     if x >= 1 << 4 {
23336fd0130Shoumkh         x >>= 4;
23436fd0130Shoumkh         result |= 4;
23536fd0130Shoumkh     }
23636fd0130Shoumkh     if x >= 1 << 2 {
23736fd0130Shoumkh         x >>= 2;
23836fd0130Shoumkh         result |= 2;
23936fd0130Shoumkh     }
24036fd0130Shoumkh     if x >= 1 << 1 {
24136fd0130Shoumkh         result |= 1;
24236fd0130Shoumkh     }
24336fd0130Shoumkh 
24436fd0130Shoumkh     result
24536fd0130Shoumkh }
24636fd0130Shoumkh 
24736fd0130Shoumkh impl dyn Clocksource {
24836fd0130Shoumkh     /// # 计算时钟源能记录的最大时间跨度
24936fd0130Shoumkh     pub fn clocksource_max_deferment(&self) -> u64 {
25036fd0130Shoumkh         let cs_data_guard = self.clocksource_data();
25136fd0130Shoumkh         let max_nsecs: u64;
25236fd0130Shoumkh         let mut max_cycles: u64;
25336fd0130Shoumkh         max_cycles = (1 << (63 - (log2(cs_data_guard.mult) + 1))) as u64;
25436fd0130Shoumkh         max_cycles = max_cycles.min(cs_data_guard.mask.bits);
25536fd0130Shoumkh         max_nsecs = clocksource_cyc2ns(
25636fd0130Shoumkh             CycleNum(max_cycles),
25736fd0130Shoumkh             cs_data_guard.mult,
25836fd0130Shoumkh             cs_data_guard.shift,
25936fd0130Shoumkh         );
26036fd0130Shoumkh         return max_nsecs - (max_nsecs >> 5);
26136fd0130Shoumkh     }
26236fd0130Shoumkh 
26336fd0130Shoumkh     /// # 注册时钟源
26436fd0130Shoumkh     ///
26536fd0130Shoumkh     /// ## 返回值
26636fd0130Shoumkh     ///
26736fd0130Shoumkh     /// * `Ok(0)` - 时钟源注册成功。
26836fd0130Shoumkh     /// * `Err(SystemError)` - 时钟源注册失败。
26936fd0130Shoumkh     pub fn register(&self) -> Result<i32, SystemError> {
27036fd0130Shoumkh         let ns = self.clocksource_max_deferment();
27136fd0130Shoumkh         let mut cs_data = self.clocksource_data();
27236fd0130Shoumkh         cs_data.max_idle_ns = ns as u32;
27336fd0130Shoumkh         self.update_clocksource_data(cs_data)?;
27436fd0130Shoumkh         // 将时钟源加入到时钟源队列中
27536fd0130Shoumkh         self.clocksource_enqueue();
27636fd0130Shoumkh         // 将时钟源加入到监视队列中
27736fd0130Shoumkh         self.clocksource_enqueue_watchdog()
27836fd0130Shoumkh             .expect("register: failed to enqueue watchdog list");
27936fd0130Shoumkh         // 选择一个最好的时钟源
28036fd0130Shoumkh         clocksource_select();
28136fd0130Shoumkh         kdebug!("clocksource_register successfully");
28236fd0130Shoumkh         return Ok(0);
28336fd0130Shoumkh     }
28436fd0130Shoumkh 
28536fd0130Shoumkh     /// # 将时钟源插入时钟源队列
28636fd0130Shoumkh     pub fn clocksource_enqueue(&self) {
28736fd0130Shoumkh         // 根据rating由大到小排序
28836fd0130Shoumkh         let cs_data = self.clocksource_data();
28936fd0130Shoumkh         let list_guard = &mut CLOCKSOURCE_LIST.lock();
29036fd0130Shoumkh         let mut spilt_pos: usize = 0;
29136fd0130Shoumkh         for (pos, ele) in list_guard.iter().enumerate() {
29236fd0130Shoumkh             if ele.clocksource_data().rating < cs_data.rating {
29336fd0130Shoumkh                 spilt_pos = pos;
29436fd0130Shoumkh                 break;
29536fd0130Shoumkh             }
29636fd0130Shoumkh         }
29736fd0130Shoumkh         let mut temp_list = list_guard.split_off(spilt_pos);
29836fd0130Shoumkh         let cs = self.clocksource();
29936fd0130Shoumkh         list_guard.push_back(cs);
30036fd0130Shoumkh         list_guard.append(&mut temp_list);
30136fd0130Shoumkh         // kdebug!(
30236fd0130Shoumkh         //     "CLOCKSOURCE_LIST len = {:?},clocksource_enqueue sccessfully",
30336fd0130Shoumkh         //     list_guard.len()
30436fd0130Shoumkh         // );
30536fd0130Shoumkh     }
30636fd0130Shoumkh 
30736fd0130Shoumkh     /// # 将时间源插入监控队列
30836fd0130Shoumkh     ///
30936fd0130Shoumkh     /// ## 返回值
31036fd0130Shoumkh     ///
31136fd0130Shoumkh     /// * `Ok(0)` - 时间源插入监控队列成功
31236fd0130Shoumkh     /// * `Err(SystemError)` - 时间源插入监控队列失败
31336fd0130Shoumkh     pub fn clocksource_enqueue_watchdog(&self) -> Result<i32, SystemError> {
31436fd0130Shoumkh         // BUG 可能需要lock irq
31536fd0130Shoumkh         let mut cs_data = self.clocksource_data();
31636fd0130Shoumkh 
31736fd0130Shoumkh         let cs = self.clocksource();
31836fd0130Shoumkh         if cs_data
31936fd0130Shoumkh             .flags
32036fd0130Shoumkh             .contains(ClocksourceFlags::CLOCK_SOURCE_MUST_VERIFY)
32136fd0130Shoumkh         {
32236fd0130Shoumkh             let mut list_guard = WATCHDOG_LIST.lock_irqsave();
32336fd0130Shoumkh             // cs是被监视的
32436fd0130Shoumkh             cs_data
32536fd0130Shoumkh                 .flags
32636fd0130Shoumkh                 .remove(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG);
32736fd0130Shoumkh             cs.update_clocksource_data(cs_data)?;
32836fd0130Shoumkh             list_guard.push_back(cs);
32936fd0130Shoumkh         } else {
33036fd0130Shoumkh             // cs是监视器
33136fd0130Shoumkh             if cs_data
33236fd0130Shoumkh                 .flags
33336fd0130Shoumkh                 .contains(ClocksourceFlags::CLOCK_SOURCE_IS_CONTINUOUS)
33436fd0130Shoumkh             {
33536fd0130Shoumkh                 // 如果时钟设备是连续的
33636fd0130Shoumkh                 cs_data
33736fd0130Shoumkh                     .flags
33836fd0130Shoumkh                     .insert(ClocksourceFlags::CLOCK_SOURCE_VALID_FOR_HRES);
33936fd0130Shoumkh                 cs.update_clocksource_data(cs_data.clone())?;
34036fd0130Shoumkh             }
34136fd0130Shoumkh 
34236fd0130Shoumkh             // 将时钟源加入到监控队列中
34336fd0130Shoumkh             let mut list_guard = WATCHDOG_LIST.lock();
34436fd0130Shoumkh             list_guard.push_back(cs.clone());
34536fd0130Shoumkh             drop(list_guard);
34636fd0130Shoumkh 
34736fd0130Shoumkh             // 对比当前注册的时间源的精度和监视器的精度
34836fd0130Shoumkh             let cs_watchdog = &mut CLOCKSOUCE_WATCHDOG.lock();
34936fd0130Shoumkh             if cs_watchdog.watchdog.is_none()
35036fd0130Shoumkh                 || cs_data.rating
35136fd0130Shoumkh                     > cs_watchdog
35236fd0130Shoumkh                         .watchdog
35336fd0130Shoumkh                         .clone()
35436fd0130Shoumkh                         .unwrap()
35536fd0130Shoumkh                         .clocksource_data()
35636fd0130Shoumkh                         .rating
35736fd0130Shoumkh             {
35836fd0130Shoumkh                 // 当前注册的时间源的精度更高或者没有监视器,替换监视器
35936fd0130Shoumkh                 cs_watchdog.watchdog.replace(cs);
36036fd0130Shoumkh                 clocksource_reset_watchdog();
36136fd0130Shoumkh             }
36236fd0130Shoumkh 
36336fd0130Shoumkh             // 启动监视器
36436fd0130Shoumkh             cs_watchdog.clocksource_start_watchdog();
36536fd0130Shoumkh         }
36636fd0130Shoumkh         return Ok(0);
36736fd0130Shoumkh     }
36836fd0130Shoumkh 
36936fd0130Shoumkh     /// # 将时钟源标记为unstable
37036fd0130Shoumkh     ///
37136fd0130Shoumkh     /// ## 参数
37236fd0130Shoumkh     /// * `delta` - 时钟源误差
37336fd0130Shoumkh     pub fn set_unstable(&self, delta: i64) -> Result<i32, SystemError> {
37436fd0130Shoumkh         let mut cs_data = self.clocksource_data();
37536fd0130Shoumkh         // 打印出unstable的时钟源信息
37636fd0130Shoumkh         kdebug!(
37736fd0130Shoumkh             "clocksource :{:?} is unstable, its delta is {:?}",
37836fd0130Shoumkh             cs_data.name,
37936fd0130Shoumkh             delta
38036fd0130Shoumkh         );
38136fd0130Shoumkh         cs_data.flags.remove(
38236fd0130Shoumkh             ClocksourceFlags::CLOCK_SOURCE_VALID_FOR_HRES | ClocksourceFlags::CLOCK_SOURCE_WATCHDOG,
38336fd0130Shoumkh         );
38436fd0130Shoumkh         cs_data
38536fd0130Shoumkh             .flags
38636fd0130Shoumkh             .insert(ClocksourceFlags::CLOCK_SOURCE_UNSTABLE);
38736fd0130Shoumkh         self.update_clocksource_data(cs_data)?;
38836fd0130Shoumkh 
38936fd0130Shoumkh         // 启动watchdog线程 进行后续处理
39036fd0130Shoumkh         if unsafe { FINISHED_BOOTING.load(Ordering::Relaxed) } {
39136fd0130Shoumkh             // TODO 在实现了工作队列后,将启动线程换成schedule work
39236fd0130Shoumkh             unsafe { run_watchdog_kthread() }
39336fd0130Shoumkh         }
39436fd0130Shoumkh         return Ok(0);
39536fd0130Shoumkh     }
39636fd0130Shoumkh 
39736fd0130Shoumkh     /// # 将时间源从监视链表中弹出
39836fd0130Shoumkh     fn clocksource_dequeue_watchdog(&self) {
39936fd0130Shoumkh         let data = self.clocksource_data();
40036fd0130Shoumkh         let mut locked_watchdog = CLOCKSOUCE_WATCHDOG.lock();
40136fd0130Shoumkh         let watchdog = locked_watchdog
40236fd0130Shoumkh             .get_watchdog()
40336fd0130Shoumkh             .clone()
40436fd0130Shoumkh             .unwrap()
40536fd0130Shoumkh             .clocksource_data();
40636fd0130Shoumkh 
40736fd0130Shoumkh         let mut list = WATCHDOG_LIST.lock();
40836fd0130Shoumkh         let mut size = list.len();
40936fd0130Shoumkh 
41036fd0130Shoumkh         let mut del_pos: usize = size;
41136fd0130Shoumkh         for (pos, ele) in list.iter().enumerate() {
41236fd0130Shoumkh             let ele_data = ele.clocksource_data();
41336fd0130Shoumkh             if ele_data.name.eq(&data.name) && ele_data.rating.eq(&data.rating) {
41436fd0130Shoumkh                 // 记录要删除的时钟源在监视链表中的下标
41536fd0130Shoumkh                 del_pos = pos;
41636fd0130Shoumkh             }
41736fd0130Shoumkh         }
41836fd0130Shoumkh 
41936fd0130Shoumkh         if data
42036fd0130Shoumkh             .flags
42136fd0130Shoumkh             .contains(ClocksourceFlags::CLOCK_SOURCE_MUST_VERIFY)
42236fd0130Shoumkh         {
42336fd0130Shoumkh             // 如果时钟源是需要被检查的,直接删除时钟源
42436fd0130Shoumkh             if del_pos != size {
42536fd0130Shoumkh                 let mut temp_list = list.split_off(del_pos);
42636fd0130Shoumkh                 temp_list.pop_front();
42736fd0130Shoumkh                 list.append(&mut temp_list);
42836fd0130Shoumkh             }
42936fd0130Shoumkh         } else if watchdog.name.eq(&data.name) && watchdog.rating.eq(&data.rating) {
43036fd0130Shoumkh             // 如果要删除的时钟源是监视器,则需要找到一个新的监视器
43136fd0130Shoumkh             // TODO 重新设置时钟源
43236fd0130Shoumkh             // 将链表解锁防止reset中双重加锁 并释放保存的旧的watchdog的数据
43336fd0130Shoumkh 
43436fd0130Shoumkh             // 代替了clocksource_reset_watchdog()的功能,将所有时钟源的watchdog标记清除
43536fd0130Shoumkh             for ele in list.iter() {
43636fd0130Shoumkh                 ele.clocksource_data()
43736fd0130Shoumkh                     .flags
43836fd0130Shoumkh                     .remove(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG);
43936fd0130Shoumkh             }
44036fd0130Shoumkh 
44136fd0130Shoumkh             // 遍历所有时间源,寻找新的监视器
44236fd0130Shoumkh             let mut clocksource_list = CLOCKSOURCE_LIST.lock();
44336fd0130Shoumkh             let mut replace_pos: usize = clocksource_list.len();
44436fd0130Shoumkh             for (pos, ele) in clocksource_list.iter().enumerate() {
44536fd0130Shoumkh                 let ele_data = ele.clocksource_data();
44636fd0130Shoumkh 
44736fd0130Shoumkh                 if ele_data.name.eq(&data.name) && ele_data.rating.eq(&data.rating)
44836fd0130Shoumkh                     || ele_data
44936fd0130Shoumkh                         .flags
45036fd0130Shoumkh                         .contains(ClocksourceFlags::CLOCK_SOURCE_MUST_VERIFY)
45136fd0130Shoumkh                 {
45236fd0130Shoumkh                     // 当前时钟源是要被删除的时钟源或没被检查过的时钟源
45336fd0130Shoumkh                     // 不适合成为监视器
45436fd0130Shoumkh                     continue;
45536fd0130Shoumkh                 }
45636fd0130Shoumkh                 let watchdog = locked_watchdog.get_watchdog().clone();
45736fd0130Shoumkh                 if watchdog.is_none()
45836fd0130Shoumkh                     || ele_data.rating > watchdog.unwrap().clocksource_data().rating
45936fd0130Shoumkh                 {
46036fd0130Shoumkh                     // 如果watchdog不存在或者当前时钟源的精度高于watchdog的精度,则记录当前时钟源的下标
46136fd0130Shoumkh                     replace_pos = pos;
46236fd0130Shoumkh                 }
46336fd0130Shoumkh             }
46436fd0130Shoumkh             // 使用刚刚找到的更好的时钟源替换旧的watchdog
46536fd0130Shoumkh             if replace_pos < clocksource_list.len() {
46636fd0130Shoumkh                 let mut temp_list = clocksource_list.split_off(replace_pos);
46736fd0130Shoumkh                 let new_wd = temp_list.front().unwrap().clone();
46836fd0130Shoumkh                 clocksource_list.append(&mut temp_list);
46936fd0130Shoumkh                 // 替换watchdog
47036fd0130Shoumkh                 locked_watchdog.watchdog.replace(new_wd);
47136fd0130Shoumkh                 // drop(locked_watchdog);
47236fd0130Shoumkh             }
47336fd0130Shoumkh             // 删除时钟源
47436fd0130Shoumkh             if del_pos != size {
47536fd0130Shoumkh                 let mut temp_list = list.split_off(del_pos);
47636fd0130Shoumkh                 temp_list.pop_front();
47736fd0130Shoumkh                 list.append(&mut temp_list);
47836fd0130Shoumkh             }
47936fd0130Shoumkh         }
48036fd0130Shoumkh 
48136fd0130Shoumkh         // 清除watchdog标记
48236fd0130Shoumkh         let mut cs_data = self.clocksource_data();
48336fd0130Shoumkh         cs_data
48436fd0130Shoumkh             .flags
48536fd0130Shoumkh             .remove(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG);
48636fd0130Shoumkh         self.update_clocksource_data(cs_data)
48736fd0130Shoumkh             .expect("clocksource_dequeue_watchdog: failed to update clocksource data");
48836fd0130Shoumkh         size = list.len();
48936fd0130Shoumkh         // 停止当前的watchdog
49036fd0130Shoumkh         locked_watchdog.clocksource_stop_watchdog(size - 1);
49136fd0130Shoumkh     }
49236fd0130Shoumkh 
49336fd0130Shoumkh     /// # 将时钟源从时钟源链表中弹出
49436fd0130Shoumkh     fn clocksource_dequeue(&self) {
49536fd0130Shoumkh         let mut list = CLOCKSOURCE_LIST.lock();
49636fd0130Shoumkh         let data = self.clocksource_data();
49736fd0130Shoumkh         let mut del_pos: usize = list.len();
49836fd0130Shoumkh         for (pos, ele) in list.iter().enumerate() {
49936fd0130Shoumkh             let ele_data = ele.clocksource_data();
50036fd0130Shoumkh             if ele_data.name.eq(&data.name) && ele_data.rating.eq(&data.rating) {
50136fd0130Shoumkh                 // 记录时钟源在链表中的下标
50236fd0130Shoumkh                 del_pos = pos;
50336fd0130Shoumkh             }
50436fd0130Shoumkh         }
50536fd0130Shoumkh 
50636fd0130Shoumkh         // 删除时钟源
50736fd0130Shoumkh         if del_pos != list.len() {
50836fd0130Shoumkh             let mut temp_list = list.split_off(del_pos);
50936fd0130Shoumkh             temp_list.pop_front();
51036fd0130Shoumkh             list.append(&mut temp_list);
51136fd0130Shoumkh         }
51236fd0130Shoumkh     }
51336fd0130Shoumkh 
51436fd0130Shoumkh     /// # 注销时钟源
51536fd0130Shoumkh     #[allow(dead_code)]
51636fd0130Shoumkh     pub fn unregister(&self) {
51736fd0130Shoumkh         // 将时钟源从监视链表中弹出
51836fd0130Shoumkh         self.clocksource_dequeue_watchdog();
51936fd0130Shoumkh         // 将时钟源从时钟源链表中弹出
52036fd0130Shoumkh         self.clocksource_dequeue();
52136fd0130Shoumkh         // 检查是否有更好的时钟源
52236fd0130Shoumkh         clocksource_select();
52336fd0130Shoumkh     }
52436fd0130Shoumkh     /// # 修改时钟源的精度
52536fd0130Shoumkh     ///
52636fd0130Shoumkh     /// ## 参数
52736fd0130Shoumkh     ///
52836fd0130Shoumkh     /// * `rating` - 指定的时钟精度
52936fd0130Shoumkh     fn clocksource_change_rating(&self, rating: i32) {
53036fd0130Shoumkh         // 将时钟源从链表中弹出
53136fd0130Shoumkh         self.clocksource_dequeue();
53236fd0130Shoumkh         let mut data = self.clocksource_data();
53336fd0130Shoumkh         // 修改时钟源的精度
53436fd0130Shoumkh         data.set_rating(rating);
53536fd0130Shoumkh         self.update_clocksource_data(data)
53636fd0130Shoumkh             .expect("clocksource_change_rating:updata clocksource failed");
53736fd0130Shoumkh         // 插入时钟源到时钟源链表中
53836fd0130Shoumkh         self.clocksource_enqueue();
53936fd0130Shoumkh         // 检查是否有更好的时钟源
54036fd0130Shoumkh         clocksource_select();
54136fd0130Shoumkh     }
54236fd0130Shoumkh }
54336fd0130Shoumkh 
54436fd0130Shoumkh #[derive(Debug, Clone)]
54536fd0130Shoumkh pub struct ClocksourceData {
54636fd0130Shoumkh     /// 时钟源名字
54736fd0130Shoumkh     pub name: String,
54836fd0130Shoumkh     /// 时钟精度
54936fd0130Shoumkh     pub rating: i32,
55036fd0130Shoumkh     pub mask: ClocksourceMask,
55136fd0130Shoumkh     pub mult: u32,
55236fd0130Shoumkh     pub shift: u32,
55336fd0130Shoumkh     pub max_idle_ns: u32,
55436fd0130Shoumkh     pub flags: ClocksourceFlags,
55536fd0130Shoumkh     pub watchdog_last: CycleNum,
55636fd0130Shoumkh }
55736fd0130Shoumkh 
55836fd0130Shoumkh impl ClocksourceData {
55936fd0130Shoumkh     #[allow(dead_code)]
56036fd0130Shoumkh     pub fn new(
56136fd0130Shoumkh         name: String,
56236fd0130Shoumkh         rating: i32,
56336fd0130Shoumkh         mask: ClocksourceMask,
56436fd0130Shoumkh         mult: u32,
56536fd0130Shoumkh         shift: u32,
56636fd0130Shoumkh         max_idle_ns: u32,
56736fd0130Shoumkh         flags: ClocksourceFlags,
56836fd0130Shoumkh     ) -> Self {
56936fd0130Shoumkh         let csd = ClocksourceData {
57036fd0130Shoumkh             name,
57136fd0130Shoumkh             rating,
57236fd0130Shoumkh             mask,
57336fd0130Shoumkh             mult,
57436fd0130Shoumkh             shift,
57536fd0130Shoumkh             max_idle_ns,
57636fd0130Shoumkh             flags,
57736fd0130Shoumkh             watchdog_last: CycleNum(0),
57836fd0130Shoumkh         };
57936fd0130Shoumkh         return csd;
58036fd0130Shoumkh     }
58136fd0130Shoumkh 
58236fd0130Shoumkh     pub fn set_name(&mut self, name: String) {
58336fd0130Shoumkh         self.name = name;
58436fd0130Shoumkh     }
58536fd0130Shoumkh     pub fn set_rating(&mut self, rating: i32) {
58636fd0130Shoumkh         self.rating = rating;
58736fd0130Shoumkh     }
58836fd0130Shoumkh     pub fn set_mask(&mut self, mask: ClocksourceMask) {
58936fd0130Shoumkh         self.mask = mask;
59036fd0130Shoumkh     }
59136fd0130Shoumkh     pub fn set_mult(&mut self, mult: u32) {
59236fd0130Shoumkh         self.mult = mult;
59336fd0130Shoumkh     }
59436fd0130Shoumkh     pub fn set_shift(&mut self, shift: u32) {
59536fd0130Shoumkh         self.shift = shift;
59636fd0130Shoumkh     }
59736fd0130Shoumkh     pub fn set_max_idle_ns(&mut self, max_idle_ns: u32) {
59836fd0130Shoumkh         self.max_idle_ns = max_idle_ns;
59936fd0130Shoumkh     }
60036fd0130Shoumkh     pub fn set_flags(&mut self, flags: ClocksourceFlags) {
60136fd0130Shoumkh         self.flags = flags;
60236fd0130Shoumkh     }
60336fd0130Shoumkh     #[allow(dead_code)]
60436fd0130Shoumkh     pub fn remove_flags(&mut self, flags: ClocksourceFlags) {
60536fd0130Shoumkh         self.flags.remove(flags)
60636fd0130Shoumkh     }
60736fd0130Shoumkh     #[allow(dead_code)]
60836fd0130Shoumkh     pub fn insert_flags(&mut self, flags: ClocksourceFlags) {
60936fd0130Shoumkh         self.flags.insert(flags)
61036fd0130Shoumkh     }
61136fd0130Shoumkh }
61236fd0130Shoumkh 
61336fd0130Shoumkh ///  converts clocksource cycles to nanoseconds
61436fd0130Shoumkh ///
61536fd0130Shoumkh pub fn clocksource_cyc2ns(cycles: CycleNum, mult: u32, shift: u32) -> u64 {
61636fd0130Shoumkh     return (cycles.data() * mult as u64) >> shift;
61736fd0130Shoumkh }
61836fd0130Shoumkh 
61936fd0130Shoumkh /// # 重启所有的时间源
62036fd0130Shoumkh #[allow(dead_code)]
62136fd0130Shoumkh pub fn clocksource_resume() {
62236fd0130Shoumkh     let list = CLOCKSOURCE_LIST.lock();
62336fd0130Shoumkh     for ele in list.iter() {
62436fd0130Shoumkh         let data = ele.clocksource_data();
62536fd0130Shoumkh         match ele.resume() {
62636fd0130Shoumkh             Ok(_) => continue,
62736fd0130Shoumkh             Err(_) => {
62840fe15e0SLoGin                 kdebug!("clocksource {:?} resume failed", data.name);
62936fd0130Shoumkh             }
63036fd0130Shoumkh         }
63136fd0130Shoumkh     }
63236fd0130Shoumkh     clocksource_resume_watchdog();
63336fd0130Shoumkh }
63436fd0130Shoumkh 
63536fd0130Shoumkh /// # 暂停所有的时间源
63636fd0130Shoumkh #[allow(dead_code)]
63736fd0130Shoumkh pub fn clocksource_suspend() {
63836fd0130Shoumkh     let list = CLOCKSOURCE_LIST.lock();
63936fd0130Shoumkh     for ele in list.iter() {
64036fd0130Shoumkh         let data = ele.clocksource_data();
64136fd0130Shoumkh         match ele.suspend() {
64236fd0130Shoumkh             Ok(_) => continue,
64336fd0130Shoumkh             Err(_) => {
64440fe15e0SLoGin                 kdebug!("clocksource {:?} suspend failed", data.name);
64536fd0130Shoumkh             }
64636fd0130Shoumkh         }
64736fd0130Shoumkh     }
64836fd0130Shoumkh }
64936fd0130Shoumkh 
65036fd0130Shoumkh /// # 根据watchdog的精度,来检查被监视的时钟源的误差
65136fd0130Shoumkh ///
65236fd0130Shoumkh /// ## 返回值
65336fd0130Shoumkh ///
65436fd0130Shoumkh /// * `Ok()` - 检查完成
65536fd0130Shoumkh /// * `Err(SystemError)` - 错误码
65636fd0130Shoumkh pub fn clocksource_watchdog() -> Result<(), SystemError> {
65736fd0130Shoumkh     let mut cs_watchdog = CLOCKSOUCE_WATCHDOG.lock();
65836fd0130Shoumkh 
65936fd0130Shoumkh     // watchdog没有在运行的话直接退出
66036fd0130Shoumkh     if !cs_watchdog.is_running || cs_watchdog.watchdog.is_none() {
66136fd0130Shoumkh         return Ok(());
66236fd0130Shoumkh     }
66336fd0130Shoumkh     let cur_watchdog = cs_watchdog.watchdog.as_ref().unwrap().clone();
66436fd0130Shoumkh     let cur_wd_data = cur_watchdog.as_ref().clocksource_data();
66536fd0130Shoumkh     let cur_wd_nowclock = cur_watchdog.as_ref().read().data();
66636fd0130Shoumkh 
66736fd0130Shoumkh     let wd_last = cs_watchdog.last_check.data();
66836fd0130Shoumkh     let wd_dev_nsec = clocksource_cyc2ns(
66936fd0130Shoumkh         CycleNum((cur_wd_nowclock - wd_last) & cur_wd_data.mask.bits),
67036fd0130Shoumkh         cur_wd_data.mult,
67136fd0130Shoumkh         cur_wd_data.shift,
67236fd0130Shoumkh     );
67336fd0130Shoumkh     cs_watchdog.last_check = CycleNum(cur_wd_nowclock);
67436fd0130Shoumkh     drop(cs_watchdog);
67536fd0130Shoumkh     let watchdog_list = &mut WATCHDOG_LIST.lock();
67636fd0130Shoumkh     for cs in watchdog_list.iter() {
67736fd0130Shoumkh         let mut cs_data = cs.clocksource_data();
67836fd0130Shoumkh         // 判断时钟源是否已经被标记为不稳定
67936fd0130Shoumkh         if cs_data
68036fd0130Shoumkh             .flags
68136fd0130Shoumkh             .contains(ClocksourceFlags::CLOCK_SOURCE_UNSTABLE)
68236fd0130Shoumkh         {
68336fd0130Shoumkh             // 启动watchdog_kthread
68436fd0130Shoumkh             unsafe { run_watchdog_kthread() };
68536fd0130Shoumkh             continue;
68636fd0130Shoumkh         }
68736fd0130Shoumkh         // 读取时钟源现在的时间
68836fd0130Shoumkh         let cs_now_clock = cs.read();
68936fd0130Shoumkh 
69036fd0130Shoumkh         // 如果时钟源没有被监视,则开始监视他
69136fd0130Shoumkh         if !cs_data
69236fd0130Shoumkh             .flags
69336fd0130Shoumkh             .contains(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG)
69436fd0130Shoumkh         {
69536fd0130Shoumkh             cs_data
69636fd0130Shoumkh                 .flags
69736fd0130Shoumkh                 .insert(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG);
69836fd0130Shoumkh             // 记录此次检查的时刻
69936fd0130Shoumkh             cs_data.watchdog_last = cs_now_clock;
70036fd0130Shoumkh             cs.update_clocksource_data(cs_data.clone())?;
70136fd0130Shoumkh             continue;
70236fd0130Shoumkh         }
70336fd0130Shoumkh 
70436fd0130Shoumkh         // 计算时钟源的误差
70536fd0130Shoumkh         let cs_dev_nsec = clocksource_cyc2ns(
70636fd0130Shoumkh             CycleNum(cs_now_clock.div(cs_data.watchdog_last).data() & cs_data.mask.bits),
70736fd0130Shoumkh             cs_data.mult,
70836fd0130Shoumkh             cs_data.shift,
70936fd0130Shoumkh         );
71036fd0130Shoumkh         // 记录此次检查的时刻
71136fd0130Shoumkh         cs_data.watchdog_last = cs_now_clock;
71236fd0130Shoumkh         cs.update_clocksource_data(cs_data.clone())?;
71336fd0130Shoumkh         if cs_dev_nsec.abs_diff(wd_dev_nsec) > WATCHDOG_THRESHOLD.into() {
71436fd0130Shoumkh             // 误差过大,标记为unstable
71536fd0130Shoumkh             cs.set_unstable((cs_dev_nsec - wd_dev_nsec).try_into().unwrap())?;
71636fd0130Shoumkh             continue;
71736fd0130Shoumkh         }
71836fd0130Shoumkh 
71936fd0130Shoumkh         // 判断是否要切换为高精度模式
72036fd0130Shoumkh         if !cs_data
72136fd0130Shoumkh             .flags
72236fd0130Shoumkh             .contains(ClocksourceFlags::CLOCK_SOURCE_VALID_FOR_HRES)
72336fd0130Shoumkh             && cs_data
72436fd0130Shoumkh                 .flags
72536fd0130Shoumkh                 .contains(ClocksourceFlags::CLOCK_SOURCE_IS_CONTINUOUS)
72636fd0130Shoumkh             && cur_wd_data
72736fd0130Shoumkh                 .flags
72836fd0130Shoumkh                 .contains(ClocksourceFlags::CLOCK_SOURCE_IS_CONTINUOUS)
72936fd0130Shoumkh         {
73036fd0130Shoumkh             cs_data
73136fd0130Shoumkh                 .flags
73236fd0130Shoumkh                 .insert(ClocksourceFlags::CLOCK_SOURCE_VALID_FOR_HRES);
73336fd0130Shoumkh             cs.update_clocksource_data(cs_data)?;
73436fd0130Shoumkh             // TODO 通知tick机制 切换为高精度模式
73536fd0130Shoumkh         }
73636fd0130Shoumkh         let mut cs_watchdog = CLOCKSOUCE_WATCHDOG.lock();
73736fd0130Shoumkh         // FIXME 需要保证所有cpu时间统一
73836fd0130Shoumkh         cs_watchdog.timer_expires += WATCHDOG_INTERVAL;
73936fd0130Shoumkh         //创建定时器执行watchdog
74036fd0130Shoumkh         let watchdog_func = Box::new(WatchdogTimerFunc {});
74136fd0130Shoumkh         let watchdog_timer = Timer::new(watchdog_func, cs_watchdog.timer_expires);
74236fd0130Shoumkh         watchdog_timer.activate();
74336fd0130Shoumkh     }
74436fd0130Shoumkh     return Ok(());
74536fd0130Shoumkh }
74636fd0130Shoumkh 
74736fd0130Shoumkh /// # watchdog线程的逻辑,执行unstable的后续操作
74836fd0130Shoumkh pub fn clocksource_watchdog_kthread() {
74936fd0130Shoumkh     let mut del_vec: Vec<usize> = Vec::new();
75036fd0130Shoumkh     let mut del_clocks: Vec<Arc<dyn Clocksource>> = Vec::new();
75136fd0130Shoumkh     let wd_list = &mut WATCHDOG_LIST.lock();
75236fd0130Shoumkh 
75336fd0130Shoumkh     // 将不稳定的时钟源弹出监视链表
75436fd0130Shoumkh     for (pos, ele) in wd_list.iter().enumerate() {
75536fd0130Shoumkh         let data = ele.clocksource_data();
75636fd0130Shoumkh         if data.flags.contains(ClocksourceFlags::CLOCK_SOURCE_UNSTABLE) {
75736fd0130Shoumkh             del_vec.push(pos);
75836fd0130Shoumkh             del_clocks.push(ele.clone());
75936fd0130Shoumkh         }
76036fd0130Shoumkh     }
76136fd0130Shoumkh     for pos in del_vec {
76236fd0130Shoumkh         let mut temp_list = wd_list.split_off(pos);
76336fd0130Shoumkh         temp_list.pop_front();
76436fd0130Shoumkh         wd_list.append(&mut temp_list);
76536fd0130Shoumkh     }
76636fd0130Shoumkh 
76736fd0130Shoumkh     // 检查是否需要停止watchdog
76836fd0130Shoumkh     CLOCKSOUCE_WATCHDOG
76936fd0130Shoumkh         .lock()
77036fd0130Shoumkh         .clocksource_stop_watchdog(wd_list.len());
77136fd0130Shoumkh     // 将不稳定的时钟源精度都设置为最低
77236fd0130Shoumkh     for clock in del_clocks.iter() {
77336fd0130Shoumkh         clock.clocksource_change_rating(0);
77436fd0130Shoumkh     }
77536fd0130Shoumkh }
77636fd0130Shoumkh 
77736fd0130Shoumkh /// # 清空所有时钟源的watchdog标志位
77836fd0130Shoumkh pub fn clocksource_reset_watchdog() {
77936fd0130Shoumkh     let list_guard = WATCHDOG_LIST.lock();
78036fd0130Shoumkh     for ele in list_guard.iter() {
78136fd0130Shoumkh         ele.clocksource_data()
78236fd0130Shoumkh             .flags
78336fd0130Shoumkh             .remove(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG);
78436fd0130Shoumkh     }
78536fd0130Shoumkh }
78636fd0130Shoumkh 
78736fd0130Shoumkh /// # 重启检查器
78836fd0130Shoumkh pub fn clocksource_resume_watchdog() {
78936fd0130Shoumkh     clocksource_reset_watchdog();
79036fd0130Shoumkh }
79136fd0130Shoumkh 
79236fd0130Shoumkh /// # 根据精度选择最优的时钟源,或者接受用户指定的时间源
79336fd0130Shoumkh pub fn clocksource_select() {
79436fd0130Shoumkh     let list_guard = CLOCKSOURCE_LIST.lock();
79536fd0130Shoumkh     if unsafe { FINISHED_BOOTING.load(Ordering::Relaxed) } || list_guard.is_empty() {
79636fd0130Shoumkh         return;
79736fd0130Shoumkh     }
79836fd0130Shoumkh     let mut best = list_guard.front().unwrap().clone();
79936fd0130Shoumkh     let override_name = OVERRIDE_NAME.lock();
80036fd0130Shoumkh     // 判断是否有用户空间指定的时间源
80136fd0130Shoumkh     for ele in list_guard.iter() {
80236fd0130Shoumkh         if ele.clocksource_data().name.eq(override_name.deref()) {
80336fd0130Shoumkh             // TODO 判断是否是高精度模式
80436fd0130Shoumkh             // 暂时不支持高精度模式
80536fd0130Shoumkh             // 如果是高精度模式,但是时钟源不支持高精度模式的话,就要退出循环
80636fd0130Shoumkh             best = ele.clone();
80736fd0130Shoumkh             break;
80836fd0130Shoumkh         }
80936fd0130Shoumkh     }
81036fd0130Shoumkh     // 对比当前的时钟源和记录到最好的时钟源的精度
81136fd0130Shoumkh     if CUR_CLOCKSOURCE.lock().as_ref().is_some() {
81236fd0130Shoumkh         // 当前时钟源不为空
81336fd0130Shoumkh         let cur_clocksource = CUR_CLOCKSOURCE.lock().as_ref().unwrap().clone();
81436fd0130Shoumkh         let best_name = &best.clocksource_data().name;
81536fd0130Shoumkh         if cur_clocksource.clocksource_data().name.ne(best_name) {
81636fd0130Shoumkh             kinfo!("Switching to the clocksource {:?}\n", best_name);
81736fd0130Shoumkh             drop(cur_clocksource);
81836fd0130Shoumkh             CUR_CLOCKSOURCE.lock().replace(best);
81936fd0130Shoumkh             // TODO 通知timerkeeping 切换了时间源
82036fd0130Shoumkh         }
82136fd0130Shoumkh     } else {
82236fd0130Shoumkh         // 当前时钟源为空
82336fd0130Shoumkh         CUR_CLOCKSOURCE.lock().replace(best);
82436fd0130Shoumkh     }
82536fd0130Shoumkh     kdebug!(" clocksource_select finish");
82636fd0130Shoumkh }
82736fd0130Shoumkh 
82836fd0130Shoumkh /// # clocksource模块加载完成
82936fd0130Shoumkh pub fn clocksource_boot_finish() {
83036fd0130Shoumkh     let mut cur_clocksource = CUR_CLOCKSOURCE.lock();
83136fd0130Shoumkh     cur_clocksource.replace(clocksource_default_clock());
83236fd0130Shoumkh     unsafe { FINISHED_BOOTING.store(true, Ordering::Relaxed) };
83336fd0130Shoumkh     // 清除不稳定的时钟源
83436fd0130Shoumkh     clocksource_watchdog_kthread();
83536fd0130Shoumkh     kdebug!("clocksource_boot_finish");
83636fd0130Shoumkh }
83736fd0130Shoumkh 
83836fd0130Shoumkh // ======== 以下为对C的接口 ========
83936fd0130Shoumkh /// # 完成对clocksource模块的加载
84036fd0130Shoumkh #[no_mangle]
84136fd0130Shoumkh pub extern "C" fn rs_clocksource_boot_finish() {
84236fd0130Shoumkh     clocksource_boot_finish();
84336fd0130Shoumkh }
84436fd0130Shoumkh 
84536fd0130Shoumkh /// # 启动watchdog线程的辅助函数
84636fd0130Shoumkh #[no_mangle]
84736fd0130Shoumkh pub extern "C" fn rs_clocksource_watchdog_kthread(_data: c_void) -> i32 {
84836fd0130Shoumkh     clocksource_watchdog_kthread();
84936fd0130Shoumkh     return 0;
85036fd0130Shoumkh }
851