《操作系统》的实验代码。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

163 lines
4.9 KiB

10 years ago
  1. #include <defs.h>
  2. #include <list.h>
  3. #include <proc.h>
  4. #include <assert.h>
  5. #include <default_sched.h>
  6. #define USE_SKEW_HEAP 1
  7. /* You should define the BigStride constant here*/
  8. /* LAB6: YOUR CODE */
  9. #define BIG_STRIDE 0x7FFFFFFF /* ??? */
  10. /* The compare function for two skew_heap_node_t's and the
  11. * corresponding procs*/
  12. static int
  13. proc_stride_comp_f(void *a, void *b)
  14. {
  15. struct proc_struct *p = le2proc(a, lab6_run_pool);
  16. struct proc_struct *q = le2proc(b, lab6_run_pool);
  17. int32_t c = p->lab6_stride - q->lab6_stride;
  18. if (c > 0) return 1;
  19. else if (c == 0) return 0;
  20. else return -1;
  21. }
  22. /*
  23. * stride_init initializes the run-queue rq with correct assignment for
  24. * member variables, including:
  25. *
  26. * - run_list: should be a empty list after initialization.
  27. * - lab6_run_pool: NULL
  28. * - proc_num: 0
  29. * - max_time_slice: no need here, the variable would be assigned by the caller.
  30. *
  31. * hint: see proj13.1/libs/list.h for routines of the list structures.
  32. */
  33. static void
  34. stride_init(struct run_queue *rq) {
  35. /* LAB6: YOUR CODE */
  36. list_init(&(rq->run_list));
  37. rq->lab6_run_pool = NULL;
  38. rq->proc_num = 0;
  39. }
  40. /*
  41. * stride_enqueue inserts the process ``proc'' into the run-queue
  42. * ``rq''. The procedure should verify/initialize the relevant members
  43. * of ``proc'', and then put the ``lab6_run_pool'' node into the
  44. * queue(since we use priority queue here). The procedure should also
  45. * update the meta date in ``rq'' structure.
  46. *
  47. * proc->time_slice denotes the time slices allocation for the
  48. * process, which should set to rq->max_time_slice.
  49. *
  50. * hint: see proj13.1/libs/skew_heap.h for routines of the priority
  51. * queue structures.
  52. */
  53. static void
  54. stride_enqueue(struct run_queue *rq, struct proc_struct *proc) {
  55. /* LAB6: YOUR CODE */
  56. #if USE_SKEW_HEAP
  57. rq->lab6_run_pool =
  58. skew_heap_insert(rq->lab6_run_pool, &(proc->lab6_run_pool), proc_stride_comp_f);
  59. #else
  60. assert(list_empty(&(proc->run_link)));
  61. list_add_before(&(rq->run_list), &(proc->run_link));
  62. #endif
  63. if (proc->time_slice == 0 || proc->time_slice > rq->max_time_slice) {
  64. proc->time_slice = rq->max_time_slice;
  65. }
  66. proc->rq = rq;
  67. rq->proc_num ++;
  68. }
  69. /*
  70. * stride_dequeue removes the process ``proc'' from the run-queue
  71. * ``rq'', the operation would be finished by the skew_heap_remove
  72. * operations. Remember to update the ``rq'' structure.
  73. *
  74. * hint: see proj13.1/libs/skew_heap.h for routines of the priority
  75. * queue structures.
  76. */
  77. static void
  78. stride_dequeue(struct run_queue *rq, struct proc_struct *proc) {
  79. /* LAB6: YOUR CODE */
  80. #if USE_SKEW_HEAP
  81. rq->lab6_run_pool =
  82. skew_heap_remove(rq->lab6_run_pool, &(proc->lab6_run_pool), proc_stride_comp_f);
  83. #else
  84. assert(!list_empty(&(proc->run_link)) && proc->rq == rq);
  85. list_del_init(&(proc->run_link));
  86. #endif
  87. rq->proc_num --;
  88. }
  89. /*
  90. * stride_pick_next pick the element from the ``run-queue'', with the
  91. * minimum value of stride, and returns the corresponding process
  92. * pointer. The process pointer would be calculated by macro le2proc,
  93. * see proj13.1/kern/process/proc.h for definition. Return NULL if
  94. * there is no process in the queue.
  95. *
  96. * When one proc structure is selected, remember to update the stride
  97. * property of the proc. (stride += BIG_STRIDE / priority)
  98. *
  99. * hint: see proj13.1/libs/skew_heap.h for routines of the priority
  100. * queue structures.
  101. */
  102. static struct proc_struct *
  103. stride_pick_next(struct run_queue *rq) {
  104. /* LAB6: YOUR CODE */
  105. #if USE_SKEW_HEAP
  106. if (rq->lab6_run_pool == NULL) return NULL;
  107. struct proc_struct *p = le2proc(rq->lab6_run_pool, lab6_run_pool);
  108. #else
  109. list_entry_t *le = list_next(&(rq->run_list));
  110. if (le == &rq->run_list)
  111. return NULL;
  112. struct proc_struct *p = le2proc(le, run_link);
  113. le = list_next(le);
  114. while (le != &rq->run_list)
  115. {
  116. struct proc_struct *q = le2proc(le, run_link);
  117. if ((int32_t)(p->lab6_stride - q->lab6_stride) > 0)
  118. p = q;
  119. le = list_next(le);
  120. }
  121. #endif
  122. if (p->lab6_priority == 0)
  123. p->lab6_stride += BIG_STRIDE;
  124. else p->lab6_stride += BIG_STRIDE / p->lab6_priority;
  125. return p;
  126. }
  127. /*
  128. * stride_proc_tick works with the tick event of current process. You
  129. * should check whether the time slices for current process is
  130. * exhausted and update the proc struct ``proc''. proc->time_slice
  131. * denotes the time slices left for current
  132. * process. proc->need_resched is the flag variable for process
  133. * switching.
  134. */
  135. static void
  136. stride_proc_tick(struct run_queue *rq, struct proc_struct *proc) {
  137. /* LAB6: YOUR CODE */
  138. if (proc->time_slice > 0) {
  139. proc->time_slice --;
  140. }
  141. if (proc->time_slice == 0) {
  142. proc->need_resched = 1;
  143. }
  144. }
  145. struct sched_class default_sched_class = {
  146. .name = "stride_scheduler",
  147. .init = stride_init,
  148. .enqueue = stride_enqueue,
  149. .dequeue = stride_dequeue,
  150. .pick_next = stride_pick_next,
  151. .proc_tick = stride_proc_tick,
  152. };