sched.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #include "sched.h"
  2. #include <common/kprint.h>
  3. /**
  4. * @brief 从就绪队列中取出PCB
  5. *
  6. * @return struct process_control_block*
  7. */
  8. struct process_control_block *sched_cfs_dequeue()
  9. {
  10. if (list_empty(&sched_cfs_ready_queue.proc_queue.list))
  11. {
  12. return &initial_proc_union.pcb;
  13. }
  14. struct process_control_block *proc = container_of(list_next(&sched_cfs_ready_queue.proc_queue.list), struct process_control_block, list);
  15. list_del(&proc->list);
  16. --sched_cfs_ready_queue.count;
  17. return proc;
  18. }
  19. /**
  20. * @brief 将PCB加入就绪队列
  21. *
  22. * @param pcb
  23. */
  24. void sched_cfs_enqueue(struct process_control_block *pcb)
  25. {
  26. struct process_control_block *proc = container_of(list_next(&sched_cfs_ready_queue.proc_queue.list), struct process_control_block, list);
  27. if (proc == &initial_proc_union.pcb)
  28. return;
  29. if (!(list_empty(&sched_cfs_ready_queue.proc_queue.list)))
  30. {
  31. while (proc->virtual_runtime < pcb->virtual_runtime)
  32. {
  33. proc = container_of(list_next(&proc->list), struct process_control_block, list);
  34. }
  35. }
  36. list_append(&proc->list, &pcb->list);
  37. ++sched_cfs_ready_queue.count;
  38. }
  39. /**
  40. * @brief 调度函数
  41. *
  42. */
  43. void sched_cfs()
  44. {
  45. current_pcb->flags &= ~PROC_NEED_SCHED;
  46. struct process_control_block *proc = sched_cfs_dequeue();
  47. if (current_pcb->virtual_runtime >= proc->virtual_runtime) // 当前进程运行时间大于了下一进程的运行时间,进行切换
  48. {
  49. if (current_pcb->state = PROC_RUNNING) // 本次切换由于时间片到期引发,则再次加入就绪队列,否则交由其它功能模块进行管理
  50. sched_cfs_enqueue(current_pcb);
  51. if (!sched_cfs_ready_queue.cpu_exec_proc_jiffies)
  52. {
  53. switch (proc->priority)
  54. {
  55. case 0:
  56. case 1:
  57. sched_cfs_ready_queue.cpu_exec_proc_jiffies = 4 / sched_cfs_ready_queue.count;
  58. break;
  59. case 2:
  60. default:
  61. sched_cfs_ready_queue.cpu_exec_proc_jiffies = (4 / sched_cfs_ready_queue.count) << 2;
  62. break;
  63. }
  64. }
  65. switch_proc(current_pcb, proc);
  66. }
  67. else // 不进行切换
  68. {
  69. kdebug("not switch.");
  70. sched_cfs_enqueue(current_pcb);
  71. if (!sched_cfs_ready_queue.cpu_exec_proc_jiffies)
  72. {
  73. switch (proc->priority)
  74. {
  75. case 0:
  76. case 1:
  77. sched_cfs_ready_queue.cpu_exec_proc_jiffies = 4 / sched_cfs_ready_queue.cpu_exec_proc_jiffies;
  78. break;
  79. case 2:
  80. default:
  81. sched_cfs_ready_queue.cpu_exec_proc_jiffies = (4 / sched_cfs_ready_queue.cpu_exec_proc_jiffies) << 2;
  82. break;
  83. }
  84. }
  85. kdebug("hhhh");
  86. }
  87. }
  88. /**
  89. * @brief 初始化进程调度器
  90. *
  91. */
  92. void sched_init()
  93. {
  94. memset(&sched_cfs_ready_queue, 0, sizeof(struct sched_queue_t));
  95. list_init(&sched_cfs_ready_queue.proc_queue.list);
  96. sched_cfs_ready_queue.count = 1; // 因为存在IDLE进程,因此为1
  97. sched_cfs_ready_queue.cpu_exec_proc_jiffies = 4;
  98. sched_cfs_ready_queue.proc_queue.virtual_runtime = 0x7fffffffffffffff;
  99. }