ucore lab6

ucore lab6:RR与Stride调度算法实现
本文介绍了ucore操作系统实验中涉及的两种调度算法:Round Robin和Stride Scheduling。在练习1中,分析了Round Robin调度算法的原理和ucore中的实现,包括进程时间片管理和队列操作。在练习2中,详细解释了Stride Scheduling的机制,它通过进程的Pass值来决定资源分配,确保比例公平。文章提供了相关代码和测试结果,总结了这两种调度算法的理解与实现过程。

练习1: 使用 Round Robin 调度算法(不需要编码)

完成练习0后,用make grade检查结果:

[ab6实验/练习1.png)]

和练习1中说的一样,priority部分错误,其余正确。

  • 请理解并分析sched_class中各个函数指针的用法,并接合Round Robin 调度算法描ucore的调度执行过程
  • 请在实验报告中简要说明如何设计实现”多级反馈队列调度算法“,给出概要设计,鼓励给出详细设计

sched_class

// The introduction of scheduling classes is borrrowed from Linux, and makes the 
// core scheduler quite extensible. These classes (the scheduler modules) encapsulate 
// the scheduling policies. 
//调度类是从Linux中引入的,这使得核心调度程序具有相当的可扩展性。这些类(调度程序模块)封装了调度策略。
struct sched_class {
   
   
    // 调度器名称
    const char *name;
    // 初始化运行队列
    void (*init)(struct run_queue *rq);
    // 将进程放入队列中,必须使用rq_lock调用
    void (*enqueue)(struct run_queue *rq, struct proc_struct *proc);
    // 将进程从队列中移除,必须使用rq_lock调用
    void (*dequeue)(struct run_queue *rq, struct proc_struct *proc);
    // 选择下一个可运行的任务
    struct proc_struct *(*pick_next)(struct run_queue *rq);
    // 更新调度器的时钟信息
    void (*proc_tick)(struct run_queue *rq, struct proc_struct *proc);
    /* for SMP support in the future
     *  load_balance
     *     void (*load_balance)(struct rq* rq);
     *  get some proc from this rq, used in load_balance,
     *  return value is the num of gotten proc
     *  int (*get_proc)(struct rq* rq, struct proc* procs_moved[]);
     */
};

这里我们可以看到五个函数:
sched_class_init,sched_class_enqueue,sched_class_dequeue,

sched_class_pick_nextsched_class_proc_tick

实现一个调度算法,必须具有这五个函数,才能实现一个调度算法。

RR调度算法

RR调度算法的调度思想是让所有runnable态的进程分时轮流使用CPU时间。RR调度器维护当前runnable进程的有序运行队列。当前进程的时间片用完之后,调度器将当前进程放置到运行队列的尾部,再从其头部取出进程进行调度。RR调度算法的就绪队列在组织结构上也是一个双向链表,只是增加了一个成员变量,表明在此就绪进程队列中的最大执行时间片。而且在进程控制块proc_struct中增加了一个成员变量time_slice,用来记录进程当前的可运行时间片段。这是由于RR调度算法需要考虑执行进程的运行时间不能太长。在每个timer到时的时候,操作系统会递减当前执行进程的time_slice,当time_slice为0时,就意味着这个进程运行了一段时间(这个时间片段称为进程的时间片),需要把CPU让给其他进程执行,于是操作系统就需要让此进程重新回到rq的队列尾,且重置此进程的时间片为就绪队列的成员变量最大时间片max_time_slice值,然后再从rq的队列头取出一个新的进程执行。

Round Robin算法主要实现在schedule/default_sched.c中,我们逐个进行分析。

RR_init

static void
RR_init(struct run_queue *rq) {
   
   
    list_init(&(rq->run_list));
    rq->proc_num = 0;
}

比较简单,用于对进程队列进行初始化。

RR_enqueue

static void
RR_enqueue(struct run_queue *rq, struct proc_struct *proc) {
   
   
    assert(list_empty(&(proc->run_link)));
    list_add_before(&(rq->run_list), &(proc->run_link));
    if (proc->time_slice == 0 || proc->time_slice > rq->max_time_slice) {
   
   
        proc->time_slice = rq->max_time_slice;
    }
    proc->rq = rq;
    rq->proc_num ++;
}

这是一个进程入队的操作:进程队列是一个双向链表,一个进程加入队列的时候,会将其加到队尾,如果进程控制块的时间片为0或者进程的时间片大于分配给进程的最大时间片,则把它重置为max_time_slice,并更新队列的进程数量。

RR_dequeue

static void
RR_dequeue(struct run_queue *rq, struct proc_struct *proc) {
   
   
    assert(!list_empty(&(proc->run_link)) && proc->rq == rq);
    list_del_init(&(proc->run_link));
    rq
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值