Ucore_lab6

实验说明

  • libs/skew_heap.h: 提供了基本的优先队列数据结构,为本次实验提供了抽象数据结构方面的支持。
  • kern/process/proc.[ch]:proc.h中扩展了proc_struct的成员变量,用于RR和stride调度算法。proc.c中实现了lab6_set_priority,用于设置进程的优先级。
  • kern/schedule/{sched.h,sched.c}: 定义了 ucore 的调度器框架,其中包括相关的数据结构(包括调度器的接口和运行队列的结构),和具体的运行时机制。
  • kern/schedule/{default_sched.h,default_sched.c}: 具体的 round-robin 算法,在本次实验中你需要了解其实现。
  • kern/schedule/default_sched_stride_c: Stride Scheduling调度器的基本框架,在此次实验中你需要填充其中的空白部分以实现一个完整的 Stride 调度器。
  • kern/syscall/syscall.[ch]: 增加了sys_gettime系统调用,便于用户进程获取当前时钟值;增加了sys_lab6_set_priority系统调用,便于用户进程设置进程优先级(给priority.c用)
  • user/{matrix.c,priority.c,… }: 相关的一些测试用户程序,测试调度算法的正确性,user目录下包含但不限于这些程序。在完成实验过程中,建议阅读这些测试程序,以了解这些程序的行为,便于进行调试。

练习0:填写已有实验

本实验依赖实验1/2/3/4/5。请把你做的实验2/3/4/5的代码填入本实验中代码中有“LAB1”/“LAB2”/“LAB3”/“LAB4”“LAB5”的注释相应部分。并确保编译通过。注意:为了能够正确执行lab6的测试应用程序,可能需对已完成的实验1/2/3/4/5的代码进行进一步改进。1

练习1: 使用 Round Robin 调度算法

完成练习0后,建议大家比较一下(可用kdiff3等文件比较软件)个人完成的lab5和练习0完成后的刚修改的lab6之间的区别,分析了解lab6采用RR调度算法后的执行过程。执行make grade,大部分测试用例应该通过。但执行priority.c应该过不去。

问题

  • 请理解并分析sched_calss中各个函数指针的用法,并接合Round Robin 调度算法描ucore的调度执行过程
  • init(struct run_queue * rq) 函数用来进行初始化run queue队列
  • enqueue(struct run_queue * rq, struct proc_struct * proc)用来进行将当前的线程入队
  • dequeue(struct run_queue * rq, struct proc_struct * proc)函数用来将proc线程出队
  • pick_next(struct run_queue * rq)用来在rq队列中选择一个符合条件的队列。
  • proc_tick(struct run_queue * rq, struct proc_struct * proc)用来在产生时钟中断时将proc的时间片减少,并对其进行判断是否需要调度。




    ucore的调度过程
    当线程因为wait、exit、sleep或者是时间片用完时,需要尽心调度,ucore通过schedule()函数进行调度,在这个函数中,当需要进行线程的切换时,他会先将当前的线程通过sched_class_enqueue()函数入队列,然后通过sched_class_pick_next()函数选择下一个要执行的线程并将其从队列中删除。

  • 请在实验报告中简要说明如何设计实现”多级反馈队列调度算法“,给出概要设计,鼓励给出详细设计

    • 进程在进入待调度的队列等待时,首先进入优先级最高的Q1等待。
  • 首先调度优先级高的队列中的进程。若高优先级中队列中已没有调度的进程,则调度次优先级队列中的进程
  • 对于同一个队列中的各个进程,按照时间片轮转法调度。比如Q1队列的时间片为N,那么Q1中的作业在经历了N个时间片后若还没有完成,则进入Q2队列等待,若Q2的时间片用完后作业还不能完成,一直进入下一级队列,直至完成。
  • 在低优先级的队列中的进程在运行时,又有新到达的作业,那么在运行完这个时间片后,CPU马上分配给新到达的作业。

练习2: 实现 Stride Scheduling 调度算法

首先需要换掉RR调度器的实现,即用default_sched_stride_c覆盖default_sched.c。然后根据此文件和后续文档对Stride度器的相关描述,完成Stride调度算法的实现。

实现过程

  • 分为了使用skew_heap和list两种方式
  • enqueue()
    • 对于skew_heap,直接使用已经封装好的函数skew_heap_insert(),proc通过stride_proc_comp_f的比较方式插入到skew_heap中。
    • 对于list,则是通过list_add_before()函数直接将proc插入到rq队列之中。
  • dequeue()
    • 对于skew_heap,直接使用已经封装好的函数skew_heap_remove()函数将proc从skew_heap中移走。
    • 对于list,直接使用list_del_init()函数将proc从list中移除。
  • pick_next()
    • 对于skew_heap,其根节点即rq -> lab6_run_pool即为stride最小的节点,选择它即可,然后update选出的proc的stride。
    • 对于list,则需要遍历一遍,从中找出stride最小的proc,并更新它的stride。
  • proc_tick()函数
    • 每次调用时,将proc->time_slice减一,如果proc->time_slice减为了0, 则说明需要进行调度,此时将proc->need_resched置一。

你可能感兴趣的:(ucore-lab6)