jiffies.rs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. use alloc::{
  2. string::ToString,
  3. sync::{Arc, Weak},
  4. };
  5. use system_error::SystemError;
  6. use crate::{arch::time::CLOCK_TICK_RATE, kerror, kinfo, libs::spinlock::SpinLock};
  7. use super::{
  8. clocksource::{Clocksource, ClocksourceData, ClocksourceFlags, ClocksourceMask, CycleNum, HZ},
  9. timer::clock,
  10. NSEC_PER_SEC,
  11. };
  12. lazy_static! {
  13. pub static ref DEFAULT_CLOCK: Arc<ClocksourceJiffies> = ClocksourceJiffies::new();
  14. }
  15. pub const JIFFIES_SHIFT: u32 = 8;
  16. pub const LATCH: u32 = (CLOCK_TICK_RATE + (HZ as u32) / 2) / HZ as u32;
  17. pub const ACTHZ: u32 = sh_div(CLOCK_TICK_RATE, LATCH, 8);
  18. pub const TICK_NESC: u32 = (NSEC_PER_SEC + (HZ as u32) / 2) / HZ as u32;
  19. //TODO 编写测试,保证始终跳动间隔与现实一致(两种时钟源进行对拍)
  20. pub const NSEC_PER_JIFFY: u32 = (((NSEC_PER_SEC as u64) << 8) / ACTHZ as u64) as u32;
  21. pub const fn sh_div(nom: u32, den: u32, lsh: u32) -> u32 {
  22. (((nom) / (den)) << (lsh)) + ((((nom) % (den)) << (lsh)) + (den) / 2) / (den)
  23. }
  24. #[derive(Debug)]
  25. pub struct ClocksourceJiffies(SpinLock<InnerJiffies>);
  26. #[derive(Debug)]
  27. pub struct InnerJiffies {
  28. data: ClocksourceData,
  29. self_ref: Weak<ClocksourceJiffies>,
  30. }
  31. impl Clocksource for ClocksourceJiffies {
  32. fn read(&self) -> CycleNum {
  33. CycleNum::new(clock())
  34. }
  35. fn clocksource_data(&self) -> ClocksourceData {
  36. let inner = self.0.lock_irqsave();
  37. return inner.data.clone();
  38. }
  39. fn clocksource(&self) -> Arc<dyn Clocksource> {
  40. self.0.lock_irqsave().self_ref.upgrade().unwrap()
  41. }
  42. fn update_clocksource_data(&self, _data: ClocksourceData) -> Result<(), SystemError> {
  43. let d = &mut self.0.lock_irqsave().data;
  44. d.set_flags(_data.flags);
  45. d.set_mask(_data.mask);
  46. d.set_max_idle_ns(_data.max_idle_ns);
  47. d.set_mult(_data.mult);
  48. d.set_name(_data.name);
  49. d.set_rating(_data.rating);
  50. d.set_shift(_data.shift);
  51. d.watchdog_last = _data.watchdog_last;
  52. return Ok(());
  53. }
  54. fn enable(&self) -> Result<i32, SystemError> {
  55. return Ok(0);
  56. }
  57. }
  58. impl ClocksourceJiffies {
  59. pub fn new() -> Arc<Self> {
  60. let data = ClocksourceData {
  61. name: "jiffies".to_string(),
  62. rating: 1,
  63. mask: ClocksourceMask::new(0xffffffff),
  64. mult: NSEC_PER_JIFFY << JIFFIES_SHIFT,
  65. shift: JIFFIES_SHIFT,
  66. max_idle_ns: Default::default(),
  67. flags: ClocksourceFlags::new(0),
  68. watchdog_last: CycleNum::new(0),
  69. uncertainty_margin: 0,
  70. maxadj: 0,
  71. };
  72. let jiffies = Arc::new(ClocksourceJiffies(SpinLock::new(InnerJiffies {
  73. data,
  74. self_ref: Default::default(),
  75. })));
  76. jiffies.0.lock().self_ref = Arc::downgrade(&jiffies);
  77. return jiffies;
  78. }
  79. }
  80. pub fn clocksource_default_clock() -> Arc<ClocksourceJiffies> {
  81. DEFAULT_CLOCK.clone()
  82. }
  83. pub fn jiffies_init() {
  84. //注册jiffies
  85. let jiffies = clocksource_default_clock() as Arc<dyn Clocksource>;
  86. match jiffies.register(1, 0) {
  87. Ok(_) => {
  88. kinfo!("jiffies_init sccessfully");
  89. }
  90. Err(_) => {
  91. kerror!("jiffies_init failed, no default clock running");
  92. }
  93. };
  94. }
  95. #[no_mangle]
  96. pub extern "C" fn rs_jiffies_init() {
  97. jiffies_init();
  98. }