timer.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. #include "timer.h"
  2. #include <common/kprint.h>
  3. #include <driver/timers/HPET/HPET.h>
  4. #include <exception/softirq.h>
  5. #include <mm/slab.h>
  6. #include <process/process.h>
  7. #include <sched/sched.h>
  8. struct timer_func_list_t timer_func_head;
  9. static spinlock_t sched_lock;
  10. // 定时器循环阈值,每次最大执行20个定时器任务
  11. #define TIMER_RUN_CYCLE_THRESHOLD 20
  12. void test_timer()
  13. {
  14. printk_color(ORANGE, BLACK, "(test_timer)");
  15. }
  16. void timer_init()
  17. {
  18. spin_init(&sched_lock);
  19. timer_jiffies = 0;
  20. timer_func_init(&timer_func_head, NULL, NULL, -1UL);
  21. register_softirq(TIMER_SIRQ, &do_timer_softirq, NULL);
  22. struct timer_func_list_t *tmp = (struct timer_func_list_t *)kmalloc(sizeof(struct timer_func_list_t), 0);
  23. timer_func_init(tmp, &test_timer, NULL, 5);
  24. timer_func_add(tmp);
  25. kdebug("timer func initialized.");
  26. }
  27. /**
  28. * @brief 处理时间软中断
  29. *
  30. * @param data
  31. */
  32. void do_timer_softirq(void *data)
  33. {
  34. // todo: 修改这里以及 softirq 的部分,使得 timer 具有并行性
  35. struct timer_func_list_t *tmp = container_of(list_next(&timer_func_head.list), struct timer_func_list_t, list);
  36. int cycle_count = 0;
  37. while ((!list_empty(&timer_func_head.list)) && (tmp->expire_jiffies <= timer_jiffies))
  38. {
  39. spin_lock(&sched_lock);
  40. timer_func_del(tmp);
  41. tmp->func(tmp->data);
  42. kfree(tmp);
  43. spin_unlock(&sched_lock);
  44. ++cycle_count;
  45. // kdebug("SOLVE SOFT IRQ %d", cycle_count);
  46. // 当前定时器达到阈值
  47. if (cycle_count == TIMER_RUN_CYCLE_THRESHOLD)
  48. break;
  49. tmp = container_of(list_next(&timer_func_head.list), struct timer_func_list_t, list);
  50. }
  51. }
  52. /**
  53. * @brief 初始化定时功能
  54. *
  55. * @param timer_func 队列结构体
  56. * @param func 定时功能处理函数
  57. * @param data 传输的数据
  58. * @param expire_ms 定时时长(单位:ms)
  59. */
  60. void timer_func_init(struct timer_func_list_t *timer_func, void (*func)(void *data), void *data, uint64_t expire_ms)
  61. {
  62. list_init(&timer_func->list);
  63. timer_func->func = func;
  64. timer_func->data = data;
  65. timer_func->expire_jiffies = cal_next_n_ms_jiffies(expire_ms); // 设置过期的时间片
  66. }
  67. /**
  68. * @brief 初始化定时功能
  69. *
  70. * @param timer_func 队列结构体
  71. * @param func 定时功能处理函数
  72. * @param data 传输的数据
  73. * @param expire_us 定时时长(单位:us)
  74. */
  75. void timer_func_init_us(struct timer_func_list_t *timer_func, void (*func)(void *data), void *data, uint64_t expire_us)
  76. {
  77. list_init(&timer_func->list);
  78. timer_func->func = func;
  79. timer_func->data = data;
  80. timer_func->expire_jiffies = cal_next_n_us_jiffies(expire_us); // 设置过期的时间片
  81. // kdebug("timer_func->expire_jiffies=%ld",cal_next_n_us_jiffies(expire_us));
  82. }
  83. /**
  84. * @brief 将定时功能添加到列表中
  85. *
  86. * @param timer_func 待添加的定时功能
  87. */
  88. void timer_func_add(struct timer_func_list_t *timer_func)
  89. {
  90. struct timer_func_list_t *tmp = container_of(list_next(&timer_func_head.list), struct timer_func_list_t, list);
  91. if (list_empty(&timer_func_head.list) == false)
  92. while (tmp->expire_jiffies < timer_func->expire_jiffies)
  93. tmp = container_of(list_next(&tmp->list), struct timer_func_list_t, list);
  94. list_add(&tmp->list, &(timer_func->list));
  95. }
  96. /**
  97. * @brief 将定时功能从列表中删除
  98. *
  99. * @param timer_func
  100. */
  101. void timer_func_del(struct timer_func_list_t *timer_func)
  102. {
  103. list_del(&timer_func->list);
  104. }
  105. uint64_t sys_clock(struct pt_regs *regs)
  106. {
  107. return timer_jiffies;
  108. }
  109. uint64_t clock()
  110. {
  111. return timer_jiffies;
  112. }
  113. /**
  114. * @brief 辅助函数:传进schedule_timeout函数中, 然后时间一到就唤醒 pcb 指向的进程(即自身)
  115. *
  116. * @param pcb process_control_block
  117. */
  118. static void __wake_up_helper(void *pcb)
  119. {
  120. BUG_ON(pcb == NULL);
  121. BUG_ON(process_wakeup((struct process_control_block *)pcb) != 0); // 正常唤醒,返回值为0
  122. }
  123. /**
  124. * @brief 睡眠timeout的时间之后唤醒进程/线程
  125. *
  126. * @param timeout
  127. * @return long
  128. */
  129. long schedule_timeout_ms(long timeout)
  130. {
  131. if (timeout == MAX_TIMEOUT) // 无期停止, 意味着不会调用func
  132. {
  133. sched();
  134. return MAX_TIMEOUT;
  135. }
  136. else if (timeout < 0)
  137. {
  138. BUG_ON(1);
  139. return 0;
  140. }
  141. spin_lock(&sched_lock);
  142. struct timer_func_list_t timer={0};
  143. timer_func_init(&timer, &__wake_up_helper, current_pcb, timeout);
  144. timer_func_add(&timer);
  145. current_pcb->state &= ~(PROC_RUNNING);
  146. spin_unlock(&sched_lock);
  147. sched();
  148. timeout -= timer_jiffies;
  149. return timeout < 0 ? 0 : timeout;
  150. }