rcore lab3 基于优先级的分时调度算法实现

本实验主要完成了实验要求的:

  • 修改ch2的代码, 在遇到不支持的trap的时候不要panic , 而是返回-1
  • sys_write时增加对于物理内存的检查, 只能打印属于自己物理内存的信息, 超出则返回 -1
  • 通过ch2的所有test

主要思路:

  1. 实现sys_yield
    主要难点在于转发到内核的处理函数(可以借鉴其他sys_call的实现),只要简单的调用suspend_current_and_run_next()就好了
  2. 实现 sys_gettime, sys_set_priority 两个系统调用
    系统调用的转发部分和其他类似,不展开解释,主要记录下sys_gettime 和 sys_set_priority的实现,以及基于优先级调度的策略的实现
//sys_set_priority
pub fn set_priority(priority: isize) -> isize {
    if priority <= 1 {
        -1
    }else{ 
        let mut inner = TASK_MANAGER.inner.borrow_mut();
        let current_task = inner.current_task;
        let before = inner.tasks[current_task].pass;
        inner.tasks[current_task].pass = (BIG_STRIDE as isize) / priority;
        println!("SET priority : before[{}] , after[{}]" , before, inner.tasks[current_task].pass);
        priority
    }
}
//sys_gettime
pub fn get_time() -> usize {
    time::read()
}
  1. 实现 stride 调度算法
    主要原理:选择当前stride值最小的进程,__switch到running状态,并加上task的pass值. 在这样的过程中,优先级较高的增加的stride值较少,所以有更多的调度机会,即pass值与调度次数成近似反比

    fn find_next_task_stride(&self) -> Option<usize> {
        let inner = self.inner.borrow();
        let current = inner.current_task;
        let mut ans: Option<usize> = None;
        let mut min_stride = isize::MAX;
        for index in (0..self.num_app) {
            if inner.tasks[index].task_status == TaskStatus::Ready {
                if inner.tasks[index].stride < min_stride {
                    ans = Some(index);
                    min_stride = inner.tasks[index].stride;
                }
            }
        }
        ans
    }

    fn run_next_task_stride(&self) {
        if let Some(next) = self.find_next_task_stride() {
            let mut inner = self.inner.borrow_mut();
            let current = inner.current_task;
            inner.tasks[current].stride += inner.tasks[current].pass;
            inner.tasks[next].task_status = TaskStatus::Running;
            inner.current_task = next;
            let current_task_cx_ptr2 = inner.tasks[current].get_task_cx_ptr2();
            let next_task_cx_ptr2 = inner.tasks[next].get_task_cx_ptr2();
            core::mem::drop(inner);
            unsafe {
                __switch(
                    current_task_cx_ptr2,
                    next_task_cx_ptr2,
                );
            }
        } else {
            panic!("All applications completed!");
        }
    }

  1. 如果有兴趣进一步了解 stride 调度相关内容,可以尝试看看:

作者 Carl A. Waldspurger 写这个调度算法的原论文

作者 Carl A. Waldspurger 的博士生答辩slide

南开大学实验指导中对Stride算法的部分介绍

NYU OS课关于Stride Scheduling的Slide

  1. 如果有兴趣进一步了解用户态线程实现的相关内容,可以尝试看看:

user-multitask in rv64

绿色线程 in x86

x86版绿色线程的设计实现

用户级多线程的切换原理

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用CloudSim实现基于多维QoS的资源调度算法的示例代码: ```java import org.cloudbus.cloudsim.Cloudlet; import org.cloudbus.cloudsim.CloudletSchedulerSpaceShared; import org.cloudbus.cloudsim.Datacenter; import org.cloudbus.cloudsim.DatacenterBroker; import org.cloudbus.cloudsim.DatacenterCharacteristics; import org.cloudbus.cloudsim.Host; import org.cloudbus.cloudsim.Pe; import org.cloudbus.cloudsim.Storage; import org.cloudbus.cloudsim.Vm; import org.cloudbus.cloudsim.VmAllocationPolicySimple; import org.cloudbus.cloudsim.core.CloudSim; import java.util.ArrayList; import java.util.Calendar; import java.util.List; public class QoSResourceScheduling { public static void main(String[] args) { int numBrokers = 1; // 创建一个代理商 Calendar calendar = Calendar.getInstance(); boolean traceFlag = false; // 关闭日志跟踪 CloudSim.init(numBrokers, calendar, traceFlag); Datacenter datacenter = createDatacenter("Datacenter_0"); DatacenterBroker broker = createBroker(); int brokerId = broker.getId(); List<Vm> vms = createVms(brokerId); List<Cloudlet> cloudlets = createCloudlets(brokerId); broker.submitVmList(vms); broker.submitCloudletList(cloudlets); CloudSim.startSimulation(); List<Cloudlet> finishedCloudlets = broker.getCloudletReceivedList(); CloudSim.stopSimulation(); printCloudletResults(finishedCloudlets); } private static Datacenter createDatacenter(String name) { List<Host> hostList = new ArrayList<Host>(); List<Pe> peList = new ArrayList<Pe>(); int mips = 1000; peList.add(new Pe(0, new PeProvisionerSimple(mips))); int hostId = 0; int ram = 4096; // 主机内存(以MB为单位) long storage = 1000000; // 主机存储容量(以MB为单位) int bw = 10000; // 主机带宽 hostList.add(new Host(hostId, new RamProvisionerSimple(ram), new BwProvisionerSimple(bw), storage, peList, new VmSchedulerSpaceShared(peList))); String arch = "x86"; // 主机架构 String os = "Linux"; // 主机操作系统 String vmm = "Xen"; // 主机监视程序 double time_zone = 10.0; // 主机区 double cost = 3.0; // 主机每秒的成本 double costPerMem = 0.05; // 主机每MB内存的成本 double costPerStorage = 0.1; // 主机每MB存储的成本 double costPerBw = 0.1; // 主机每Mbps带宽的成本 LinkedList<Storage> storageList = new LinkedList<Storage>(); DatacenterCharacteristics characteristics = new DatacenterCharacteristics(arch, os, vmm, hostList, time_zone, cost, costPerMem, costPerStorage, costPerBw); Datacenter datacenter = null; try { datacenter = new Datacenter(name, characteristics, new VmAllocationPolicySimple(hostList), storageList, 0); } catch (Exception e) { e.printStackTrace(); } return datacenter; } private static DatacenterBroker createBroker() { DatacenterBroker broker = null; try { broker = new DatacenterBroker("Broker"); } catch (Exception e) { e.printStackTrace(); return null; } return broker; } private static List<Vm> createVms(int brokerId) { List<Vm> vms = new ArrayList<Vm>(); int vmId = 0; int mips = 1000; int size = 10000; // 虚拟机大小(以字节为单位) int ram = 512; // 虚拟机内存(以MB为单位) long bw = 1000; // 虚拟机带宽 int pesNumber = 1; // 虚拟机处理单元数量 String vmm = "Xen"; // 虚拟机监视程序 for (int i = 0; i < 10; i++) { Vm vm = new Vm(vmId, brokerId, mips, pesNumber, ram, bw, size, vmm, new CloudletSchedulerSpaceShared()); vms.add(vm); vmId++; } return vms; } private static List<Cloudlet> createCloudlets(int brokerId) { List<Cloudlet> cloudlets = new ArrayList<Cloudlet>(); int cloudletId = 0; long length = 40000; // 执行云任务所需的MI数 long fileSize = 300; // 输入文件大小(以字节为单位) long outputSize = 300; // 输出文件大小(以字节为单位) UtilizationModel utilizationModel = new UtilizationModelFull(); for (int i = 0; i < 10; i++) { Cloudlet cloudlet = new Cloudlet(cloudletId, length, 1, fileSize, outputSize, utilizationModel, utilizationModel, utilizationModel); cloudlet.setUserId(brokerId); cloudlets.add(cloudlet); cloudletId++; } return cloudlets; } private static void printCloudletResults(List<Cloudlet> cloudlets) { System.out.println("Cloudlet ID\tStatus\tData center ID\tVM ID\tTime\tStart Time\tFinish Time"); for (Cloudlet cloudlet : cloudlets) { System.out.println(cloudlet.getCloudletId() + "\t" + cloudlet.getStatusString() + "\t" + cloudlet.getResourceId() + "\t" + cloudlet.getVmId() + "\t" + cloudlet.getActualCPUTime() + "\t" + cloudlet.getExecStartTime() + "\t" + cloudlet.getFinishTime()); } } } ``` 这是一个基于多维QoS的资源调度算法的简单示例代码。你可以根据自己的需求进行调整和扩展。希望对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值