timer.rs 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. use core::sync::atomic::{AtomicBool, Ordering};
  2. use alloc::{
  3. boxed::Box,
  4. collections::LinkedList,
  5. sync::{Arc, Weak},
  6. };
  7. use crate::{
  8. arch::{
  9. asm::current::current_pcb,
  10. interrupt::{cli, sti},
  11. sched::sched,
  12. },
  13. exception::softirq::{softirq_vectors, SoftirqNumber, SoftirqVec},
  14. include::bindings::bindings::{process_control_block, process_wakeup, pt_regs, PROC_RUNNING},
  15. kdebug, kerror,
  16. libs::spinlock::SpinLock,
  17. syscall::SystemError,
  18. };
  19. const MAX_TIMEOUT: i64 = i64::MAX;
  20. const TIMER_RUN_CYCLE_THRESHOLD: usize = 20;
  21. static mut TIMER_JIFFIES: u64 = 0;
  22. lazy_static! {
  23. pub static ref TIMER_LIST: SpinLock<LinkedList<Arc<Timer>>> = SpinLock::new(LinkedList::new());
  24. }
  25. /// 定时器要执行的函数的特征
  26. pub trait TimerFunction: Send + Sync {
  27. fn run(&mut self);
  28. }
  29. /// WakeUpHelper函数对应的结构体
  30. pub struct WakeUpHelper {
  31. pcb: &'static mut process_control_block,
  32. }
  33. impl WakeUpHelper {
  34. pub fn new(pcb: &'static mut process_control_block) -> Box<WakeUpHelper> {
  35. return Box::new(WakeUpHelper { pcb });
  36. }
  37. }
  38. impl TimerFunction for WakeUpHelper {
  39. fn run(&mut self) {
  40. unsafe {
  41. process_wakeup(self.pcb);
  42. }
  43. }
  44. }
  45. pub struct Timer(SpinLock<InnerTimer>);
  46. impl Timer {
  47. /// @brief 创建一个定时器(单位:ms)
  48. ///
  49. /// @param timer_func 定时器需要执行的函数对应的结构体
  50. ///
  51. /// @param expire_jiffies 定时器结束时刻
  52. ///
  53. /// @return 定时器结构体
  54. pub fn new(timer_func: Box<dyn TimerFunction>, expire_jiffies: u64) -> Arc<Self> {
  55. let result: Arc<Timer> = Arc::new(Timer(SpinLock::new(InnerTimer {
  56. expire_jiffies,
  57. timer_func,
  58. self_ref: Weak::default(),
  59. })));
  60. result.0.lock().self_ref = Arc::downgrade(&result);
  61. return result;
  62. }
  63. /// @brief 将定时器插入到定时器链表中
  64. pub fn activate(&self) {
  65. let timer_list = &mut TIMER_LIST.lock();
  66. let inner_guard = self.0.lock();
  67. // 链表为空,则直接插入
  68. if timer_list.is_empty() {
  69. // FIXME push_timer
  70. timer_list.push_back(inner_guard.self_ref.upgrade().unwrap());
  71. return;
  72. }
  73. let mut split_pos: usize = 0;
  74. for (pos, elt) in timer_list.iter().enumerate() {
  75. if elt.0.lock().expire_jiffies > inner_guard.expire_jiffies {
  76. split_pos = pos;
  77. break;
  78. }
  79. }
  80. let mut temp_list: LinkedList<Arc<Timer>> = timer_list.split_off(split_pos);
  81. timer_list.push_back(inner_guard.self_ref.upgrade().unwrap());
  82. timer_list.append(&mut temp_list);
  83. }
  84. #[inline]
  85. fn run(&self) {
  86. self.0.lock().timer_func.run();
  87. }
  88. }
  89. /// 定时器类型
  90. pub struct InnerTimer {
  91. /// 定时器结束时刻
  92. pub expire_jiffies: u64,
  93. /// 定时器需要执行的函数结构体
  94. pub timer_func: Box<dyn TimerFunction>,
  95. /// self_ref
  96. self_ref: Weak<Timer>,
  97. }
  98. #[derive(Debug)]
  99. pub struct DoTimerSoftirq {
  100. running: AtomicBool,
  101. }
  102. impl DoTimerSoftirq {
  103. pub fn new() -> Self {
  104. return DoTimerSoftirq {
  105. running: AtomicBool::new(false),
  106. };
  107. }
  108. fn set_run(&self) -> bool {
  109. let x = self
  110. .running
  111. .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed);
  112. if x.is_ok() {
  113. return true;
  114. } else {
  115. return false;
  116. }
  117. }
  118. fn clear_run(&self) {
  119. self.running.store(false, Ordering::Release);
  120. }
  121. }
  122. impl SoftirqVec for DoTimerSoftirq {
  123. fn run(&self) {
  124. if self.set_run() == false {
  125. return;
  126. }
  127. // 最多只处理TIMER_RUN_CYCLE_THRESHOLD个计时器
  128. for _ in 0..TIMER_RUN_CYCLE_THRESHOLD {
  129. // kdebug!("DoTimerSoftirq run");
  130. let timer_list = &mut TIMER_LIST.lock();
  131. if timer_list.is_empty() {
  132. break;
  133. }
  134. if timer_list.front().unwrap().0.lock().expire_jiffies
  135. <= unsafe { TIMER_JIFFIES as u64 }
  136. {
  137. let timer = timer_list.pop_front().unwrap();
  138. drop(timer_list);
  139. timer.run();
  140. }
  141. }
  142. self.clear_run();
  143. }
  144. }
  145. /// @brief 初始化timer模块
  146. pub fn timer_init() {
  147. // FIXME 调用register_trap
  148. let do_timer_softirq = Arc::new(DoTimerSoftirq::new());
  149. softirq_vectors()
  150. .register_softirq(SoftirqNumber::TIMER, do_timer_softirq)
  151. .expect("Failed to register timer softirq");
  152. kdebug!("timer initiated successfully");
  153. }
  154. /// 计算接下来n毫秒对应的定时器时间片
  155. pub fn next_n_ms_timer_jiffies(expire_ms: u64) -> u64 {
  156. return unsafe { TIMER_JIFFIES as u64 } + 1000 * (expire_ms);
  157. }
  158. /// 计算接下来n微秒对应的定时器时间片
  159. pub fn next_n_us_timer_jiffies(expire_us: u64) -> u64 {
  160. return unsafe { TIMER_JIFFIES as u64 } + (expire_us);
  161. }
  162. /// @brief 让pcb休眠timeout个jiffies
  163. ///
  164. /// @param timeout 需要休眠的时间(单位:jiffies)
  165. ///
  166. /// @return Ok(i64) 剩余需要休眠的时间(单位:jiffies)
  167. ///
  168. /// @return Err(SystemError) 错误码
  169. pub fn schedule_timeout(mut timeout: i64) -> Result<i64, SystemError> {
  170. // kdebug!("schedule_timeout");
  171. if timeout == MAX_TIMEOUT {
  172. sched();
  173. return Ok(MAX_TIMEOUT);
  174. } else if timeout < 0 {
  175. kerror!("timeout can't less than 0");
  176. return Err(SystemError::EINVAL);
  177. } else {
  178. // 禁用中断,防止在这段期间发生调度,造成死锁
  179. cli();
  180. timeout += unsafe { TIMER_JIFFIES } as i64;
  181. let timer = Timer::new(WakeUpHelper::new(current_pcb()), timeout as u64);
  182. timer.activate();
  183. current_pcb().state &= (!PROC_RUNNING) as u64;
  184. sti();
  185. sched();
  186. let time_remaining: i64 = timeout - unsafe { TIMER_JIFFIES } as i64;
  187. if time_remaining >= 0 {
  188. // 被提前唤醒,返回剩余时间
  189. return Ok(time_remaining);
  190. } else {
  191. return Ok(0);
  192. }
  193. }
  194. }
  195. pub fn timer_get_first_expire() -> Result<u64, SystemError> {
  196. // FIXME
  197. // kdebug!("rs_timer_get_first_expire,timer_jif = {:?}", TIMER_JIFFIES);
  198. for _ in 0..10 {
  199. match TIMER_LIST.try_lock() {
  200. Ok(timer_list) => {
  201. // kdebug!("rs_timer_get_first_expire TIMER_LIST lock successfully");
  202. if timer_list.is_empty() {
  203. // kdebug!("timer_list is empty");
  204. return Ok(0);
  205. } else {
  206. // kdebug!("timer_list not empty");
  207. return Ok(timer_list.front().unwrap().0.lock().expire_jiffies);
  208. }
  209. }
  210. // 加锁失败返回啥??
  211. Err(_) => continue,
  212. }
  213. }
  214. return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
  215. }
  216. pub fn update_timer_jiffies(add_jiffies: u64) -> u64 {
  217. unsafe { TIMER_JIFFIES += add_jiffies };
  218. return unsafe { TIMER_JIFFIES };
  219. }
  220. pub fn clock() -> u64 {
  221. return unsafe { TIMER_JIFFIES };
  222. }
  223. // ====== 重构完成后请删掉extern C ======
  224. #[no_mangle]
  225. pub extern "C" fn rs_clock() -> u64 {
  226. clock()
  227. }
  228. #[no_mangle]
  229. pub extern "C" fn sys_clock(_regs: *const pt_regs) -> u64 {
  230. clock()
  231. }
  232. // ====== 以下为给C提供的接口 ======
  233. #[no_mangle]
  234. pub extern "C" fn rs_schedule_timeout(timeout: i64) -> i64 {
  235. match schedule_timeout(timeout) {
  236. Ok(v) => {
  237. return v;
  238. }
  239. Err(e) => {
  240. kdebug!("rs_schedule_timeout run failed");
  241. return e.to_posix_errno() as i64;
  242. }
  243. }
  244. }
  245. #[no_mangle]
  246. pub extern "C" fn rs_timer_init() {
  247. timer_init();
  248. }
  249. #[no_mangle]
  250. pub extern "C" fn rs_timer_next_n_ms_jiffies(expire_ms: u64) -> u64 {
  251. return next_n_ms_timer_jiffies(expire_ms);
  252. }
  253. #[no_mangle]
  254. pub extern "C" fn rs_timer_next_n_us_jiffies(expire_us: u64) -> u64 {
  255. return next_n_us_timer_jiffies(expire_us);
  256. }
  257. #[no_mangle]
  258. pub extern "C" fn rs_timer_get_first_expire() -> i64 {
  259. match timer_get_first_expire() {
  260. Ok(v) => return v as i64,
  261. Err(e) => return e.to_posix_errno() as i64,
  262. }
  263. }
  264. #[no_mangle]
  265. pub extern "C" fn rs_update_timer_jiffies(add_jiffies: u64) -> u64 {
  266. return update_timer_jiffies(add_jiffies);
  267. }