timer.rs 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. use core::{
  2. fmt::Debug,
  3. intrinsics::unlikely,
  4. sync::atomic::{compiler_fence, AtomicBool, AtomicU64, Ordering},
  5. };
  6. use alloc::{
  7. boxed::Box,
  8. sync::{Arc, Weak},
  9. vec::Vec,
  10. };
  11. use system_error::SystemError;
  12. use crate::{
  13. arch::CurrentIrqArch,
  14. exception::{
  15. softirq::{softirq_vectors, SoftirqNumber, SoftirqVec},
  16. InterruptArch,
  17. },
  18. kerror, kinfo,
  19. libs::spinlock::{SpinLock, SpinLockGuard},
  20. process::{ProcessControlBlock, ProcessManager},
  21. sched::{schedule, SchedMode},
  22. };
  23. use super::{jiffies::NSEC_PER_JIFFY, timekeeping::update_wall_time};
  24. const MAX_TIMEOUT: i64 = i64::MAX;
  25. const TIMER_RUN_CYCLE_THRESHOLD: usize = 20;
  26. static TIMER_JIFFIES: AtomicU64 = AtomicU64::new(0);
  27. lazy_static! {
  28. pub static ref TIMER_LIST: SpinLock<Vec<(u64, Arc<Timer>)>> = SpinLock::new(Vec::new());
  29. }
  30. /// 定时器要执行的函数的特征
  31. pub trait TimerFunction: Send + Sync + Debug {
  32. fn run(&mut self) -> Result<(), SystemError>;
  33. }
  34. #[derive(Debug)]
  35. /// WakeUpHelper函数对应的结构体
  36. pub struct WakeUpHelper {
  37. pcb: Arc<ProcessControlBlock>,
  38. }
  39. impl WakeUpHelper {
  40. pub fn new(pcb: Arc<ProcessControlBlock>) -> Box<WakeUpHelper> {
  41. return Box::new(WakeUpHelper { pcb });
  42. }
  43. }
  44. impl TimerFunction for WakeUpHelper {
  45. fn run(&mut self) -> Result<(), SystemError> {
  46. ProcessManager::wakeup(&self.pcb).ok();
  47. return Ok(());
  48. }
  49. }
  50. #[derive(Debug)]
  51. pub struct Timer {
  52. inner: SpinLock<InnerTimer>,
  53. }
  54. impl Timer {
  55. /// @brief 创建一个定时器(单位:ms)
  56. ///
  57. /// @param timer_func 定时器需要执行的函数对应的结构体
  58. ///
  59. /// @param expire_jiffies 定时器结束时刻
  60. ///
  61. /// @return 定时器结构体
  62. pub fn new(timer_func: Box<dyn TimerFunction>, expire_jiffies: u64) -> Arc<Self> {
  63. let result: Arc<Timer> = Arc::new(Timer {
  64. inner: SpinLock::new(InnerTimer {
  65. expire_jiffies,
  66. timer_func: Some(timer_func),
  67. self_ref: Weak::default(),
  68. triggered: false,
  69. }),
  70. });
  71. result.inner.lock().self_ref = Arc::downgrade(&result);
  72. return result;
  73. }
  74. pub fn inner(&self) -> SpinLockGuard<InnerTimer> {
  75. return self.inner.lock_irqsave();
  76. }
  77. /// @brief 将定时器插入到定时器链表中
  78. pub fn activate(&self) {
  79. let mut timer_list = TIMER_LIST.lock_irqsave();
  80. let inner_guard = self.inner();
  81. // 链表为空,则直接插入
  82. if timer_list.is_empty() {
  83. // FIXME push_timer
  84. timer_list.push((
  85. inner_guard.expire_jiffies,
  86. inner_guard.self_ref.upgrade().unwrap(),
  87. ));
  88. drop(inner_guard);
  89. drop(timer_list);
  90. compiler_fence(Ordering::SeqCst);
  91. return;
  92. }
  93. let expire_jiffies = inner_guard.expire_jiffies;
  94. let self_arc = inner_guard.self_ref.upgrade().unwrap();
  95. drop(inner_guard);
  96. let mut split_pos: usize = 0;
  97. for (pos, elt) in timer_list.iter().enumerate() {
  98. if Arc::ptr_eq(&self_arc, &elt.1) {
  99. kwarn!("Timer already in list");
  100. }
  101. if elt.0 > expire_jiffies {
  102. split_pos = pos;
  103. break;
  104. }
  105. }
  106. timer_list.insert(split_pos, (expire_jiffies, self_arc));
  107. drop(timer_list);
  108. }
  109. #[inline]
  110. fn run(&self) {
  111. let mut timer = self.inner();
  112. timer.triggered = true;
  113. let func = timer.timer_func.take();
  114. drop(timer);
  115. let r = func.map(|mut f| f.run()).unwrap_or(Ok(()));
  116. if unlikely(r.is_err()) {
  117. kerror!(
  118. "Failed to run timer function: {self:?} {:?}",
  119. r.as_ref().err().unwrap()
  120. );
  121. }
  122. }
  123. /// ## 判断定时器是否已经触发
  124. pub fn timeout(&self) -> bool {
  125. self.inner().triggered
  126. }
  127. /// ## 取消定时器任务
  128. pub fn cancel(&self) -> bool {
  129. let this_arc = self.inner().self_ref.upgrade().unwrap();
  130. TIMER_LIST
  131. .lock_irqsave()
  132. .extract_if(|x| Arc::ptr_eq(&this_arc, &x.1))
  133. .for_each(drop);
  134. true
  135. }
  136. }
  137. /// 定时器类型
  138. #[derive(Debug)]
  139. pub struct InnerTimer {
  140. /// 定时器结束时刻
  141. pub expire_jiffies: u64,
  142. /// 定时器需要执行的函数结构体
  143. pub timer_func: Option<Box<dyn TimerFunction>>,
  144. /// self_ref
  145. self_ref: Weak<Timer>,
  146. /// 判断该计时器是否触发
  147. triggered: bool,
  148. }
  149. #[derive(Debug)]
  150. pub struct DoTimerSoftirq {
  151. running: AtomicBool,
  152. }
  153. impl DoTimerSoftirq {
  154. pub fn new() -> Self {
  155. return DoTimerSoftirq {
  156. running: AtomicBool::new(false),
  157. };
  158. }
  159. fn set_run(&self) -> bool {
  160. let x = self
  161. .running
  162. .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed);
  163. return x.is_ok();
  164. }
  165. fn clear_run(&self) {
  166. self.running.store(false, Ordering::Release);
  167. }
  168. }
  169. impl SoftirqVec for DoTimerSoftirq {
  170. fn run(&self) {
  171. if !self.set_run() {
  172. return;
  173. }
  174. // 最多只处理TIMER_RUN_CYCLE_THRESHOLD个计时器
  175. for _ in 0..TIMER_RUN_CYCLE_THRESHOLD {
  176. // kdebug!("DoTimerSoftirq run");
  177. let timer_list = TIMER_LIST.try_lock_irqsave();
  178. if timer_list.is_err() {
  179. continue;
  180. }
  181. let mut timer_list = timer_list.unwrap();
  182. if timer_list.is_empty() {
  183. break;
  184. }
  185. let (front_jiffies, timer_list_front) = timer_list.first().unwrap().clone();
  186. // kdebug!("to lock timer_list_front");
  187. if front_jiffies >= TIMER_JIFFIES.load(Ordering::SeqCst) {
  188. break;
  189. }
  190. timer_list.remove(0);
  191. drop(timer_list);
  192. timer_list_front.run();
  193. }
  194. self.clear_run();
  195. }
  196. }
  197. /// 初始化系统定时器
  198. #[inline(never)]
  199. pub fn timer_init() {
  200. // FIXME 调用register_trap
  201. let do_timer_softirq = Arc::new(DoTimerSoftirq::new());
  202. softirq_vectors()
  203. .register_softirq(SoftirqNumber::TIMER, do_timer_softirq)
  204. .expect("Failed to register timer softirq");
  205. kinfo!("timer initialized successfully");
  206. }
  207. /// 计算接下来n毫秒对应的定时器时间片
  208. pub fn next_n_ms_timer_jiffies(expire_ms: u64) -> u64 {
  209. return TIMER_JIFFIES.load(Ordering::SeqCst) + expire_ms * 1000000 / NSEC_PER_JIFFY as u64;
  210. }
  211. /// 计算接下来n微秒对应的定时器时间片
  212. pub fn next_n_us_timer_jiffies(expire_us: u64) -> u64 {
  213. return TIMER_JIFFIES.load(Ordering::SeqCst) + expire_us * 1000 / NSEC_PER_JIFFY as u64;
  214. }
  215. /// @brief 让pcb休眠timeout个jiffies
  216. ///
  217. /// @param timeout 需要休眠的时间(单位:jiffies)
  218. ///
  219. /// @return Ok(i64) 剩余需要休眠的时间(单位:jiffies)
  220. ///
  221. /// @return Err(SystemError) 错误码
  222. pub fn schedule_timeout(mut timeout: i64) -> Result<i64, SystemError> {
  223. // kdebug!("schedule_timeout");
  224. if timeout == MAX_TIMEOUT {
  225. let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
  226. ProcessManager::mark_sleep(true).ok();
  227. drop(irq_guard);
  228. schedule(SchedMode::SM_PREEMPT);
  229. return Ok(MAX_TIMEOUT);
  230. } else if timeout < 0 {
  231. kerror!("timeout can't less than 0");
  232. return Err(SystemError::EINVAL);
  233. } else {
  234. // 禁用中断,防止在这段期间发生调度,造成死锁
  235. let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
  236. timeout += TIMER_JIFFIES.load(Ordering::SeqCst) as i64;
  237. let timer = Timer::new(
  238. WakeUpHelper::new(ProcessManager::current_pcb()),
  239. timeout as u64,
  240. );
  241. ProcessManager::mark_sleep(true).ok();
  242. timer.activate();
  243. drop(irq_guard);
  244. schedule(SchedMode::SM_PREEMPT);
  245. let time_remaining: i64 = timeout - TIMER_JIFFIES.load(Ordering::SeqCst) as i64;
  246. if time_remaining >= 0 {
  247. // 被提前唤醒,返回剩余时间
  248. return Ok(time_remaining);
  249. } else {
  250. return Ok(0);
  251. }
  252. }
  253. }
  254. pub fn timer_get_first_expire() -> Result<u64, SystemError> {
  255. // FIXME
  256. // kdebug!("rs_timer_get_first_expire,timer_jif = {:?}", TIMER_JIFFIES);
  257. for _ in 0..10 {
  258. match TIMER_LIST.try_lock_irqsave() {
  259. Ok(timer_list) => {
  260. // kdebug!("rs_timer_get_first_expire TIMER_LIST lock successfully");
  261. if timer_list.is_empty() {
  262. // kdebug!("timer_list is empty");
  263. return Ok(0);
  264. } else {
  265. // kdebug!("timer_list not empty");
  266. return Ok(timer_list.first().unwrap().0);
  267. }
  268. }
  269. // 加锁失败返回啥??
  270. Err(_) => continue,
  271. }
  272. }
  273. return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
  274. }
  275. /// 更新系统时间片
  276. pub fn update_timer_jiffies(add_jiffies: u64, time_us: i64) -> u64 {
  277. let prev = TIMER_JIFFIES.fetch_add(add_jiffies, Ordering::SeqCst);
  278. compiler_fence(Ordering::SeqCst);
  279. update_wall_time(time_us);
  280. compiler_fence(Ordering::SeqCst);
  281. return prev + add_jiffies;
  282. }
  283. pub fn clock() -> u64 {
  284. return TIMER_JIFFIES.load(Ordering::SeqCst);
  285. }
  286. // ====== 以下为给C提供的接口 ======
  287. #[no_mangle]
  288. pub extern "C" fn rs_timer_init() {
  289. timer_init();
  290. }