timer.rs 9.4 KB

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