lab5 lazy

image-20230822182107448

文章目录

  • Eliminate allocation from sbrk()
  • Lazy allocation
    • task
    • hints
    • 实现
  • Lazytests and Usertests
    • task
    • hints
    • 实现

Eliminate allocation from sbrk()

第一个任务是去阻止sysproc.c中的sys_sbrk()函数真的分配内存,只需要增p->sz即可

一行代码+注释即可

uint64
sys_sbrk(void) {
    int addr;
    int n;

    if (argint(0, &n) < 0)
        return -1;
    addr = myproc()->sz;
    myproc()->sz += n;
    // if(growproc(n) < 0)
    //   return -1;
    return addr;
}

这时候会发生两个错误

image-20230822161829120

  1. usertrap的错误
    1. 页面错误是由硬件触发的,当硬件发现pte中的有效位为0时,就会陷入内核,并且设置r_scause为页错误相关的标志
  2. uvmunmap错误
    1. 有可能一个进程申请了一块内存,但是却没有真正使用,所以页表中是没有对应的一项的
    2. 结果在之后销毁这块内存的时候,还是会去页表中删除这一项,这一删就发现, 根本没有被mapped

Lazy allocation

task

  1. 修改trap.c中的代码,使其能够对用户空间的页错误进行反应

    通过映射一个新分配的物理内存页到出错的地址,并返回到用户空间使得进程继续执行

  2. 视情况修改其他的内核代码

hints

  1. 你可以通过检查r_scause是13还是15来判断是否是一个页错误
  2. r_stval()存储了引起错误的虚拟地址
  3. uvmalloc函数学习,你需要调用kallocmappages
  4. 使用PGROUNDDOWN(va)去得到虚拟页面的地址
  5. 修改uvmunmap()使其在碰到一个页面没有被mapped时不要panic
  6. 如果内核崩了,在汇编代码中查看sepc
  7. 使用你的vmprint函数去打印页表
  8. 如果出现incomplete type proc,去includespinlock.hproc.h

实现

usertrap中增加一个else if分支,关键操作就是kalloc和mappages,即申请一个操作,再增加一个映射

    } else if (r_scause() == 13 || r_scause() == 15) {
        uint64 va = r_stval();
        // 虚拟地址本来就不合法
        if (va >= p->sz) {
            p->killed = 1;
        } else {
            uint64 pa = (uint64)kalloc();
            // 内存用完了, 杀死进程
            if (pa == 0) {
                p->killed = 1;
            } else {
                va = PGROUNDDOWN(va);
                // 增加映射,如果失败了
                if (mappages(p->pagetable, va, PGSIZE, pa, PTE_W | PTE_X | PTE_R | PTE_U) != 0) {
                    kfree((void *)pa);
                    p->killed = 1;
                }
            }
        }
    } else {
        printf("usertrap(): unexpected scause %p pid=%d\n", r_scause(), p->pid);
        printf("            sepc=%p stval=%p\n", r_sepc(), r_stval());
        p->killed = 1;
    }

uvmunmap中修改为

        if ((*pte & PTE_V) == 0)
            continue;

就成功了

image-20230822163902501

Lazytests and Usertests

task

  1. 通过lazytestsusertests

hints

  1. 处理sbrk的参数为负数的情况
  2. 如果一个进程访问的虚拟地址超过了通过sbrk分配的
  3. 正确处理fork中父进程到子进程的内存拷贝
  4. 正确处理一个进程通过系统调用read或者write传递了一个合法的虚拟地址,但是对应的内存地址却没有被分配
  5. 正确处理内存用完的限制,即kalloc如果失败,则杀死进程
  6. 处理用户堆栈下面无用的页面错误,即guardpage

一个一个hins来

实现

第1个是参数为负数,特判一下就行,如果是负数,就按原来的方式处理

    if (n > 0) {
        myproc()->sz += n;
    } else {
        if (growproc(n) < 0)
            return -1;
    }

第2个和第6个通过这个判断就可以搞定

va >= p->sz || va < p->trapframe->sp

有个之前没搞清楚的点,那就是通过p->trapframe->sp取得的是栈顶指针,栈指针又是向下走的。而栈指针往下,除了一个guardpage是没有映射之外,其他的page都应该是有映射的,即pte的有效位为0。因此,如果引发了页故障并且地址还低于栈顶指针,说明肯定是碰到了guardpage的

第3个其实说的是uvmcopy函数,这个函数就是将父进程的页表原模原样的拷贝给子进程,但是有的虚拟页面连父节点自己都没有映射,子节点哪来的映射,因此碰到找不到pte或者pte有问题的情况,直接continue就行了

        if ((pte = walk(old, i, 0)) == 0)
            continue;
        // panic("uvmcopy: pte should exist");
        if ((*pte & PTE_V) == 0)
            continue;
        // panic("uvmcopy: page not present");

第4个的问题在于,如果是系统调用,那它会先在usertrap中进入syscall的处理流程,不会进入我们新添加的流程,所以会有问题

通过对write函数的不断追踪,可以发现,牵扯到的是walkaddr函数。其实就是现在需要使用这个地址了,但是原始的walkaddr不能正确返回一个物理地址,因为压根就没有。所以在walkaddr中增加创建映射的代码即可

    if ((*pte & PTE_V) == 0) {
        struct proc *p = myproc();
        // 地址不合法
        if (va >= p->sz || va < p->trapframe->sp) {
            return 0;
        }
        uint64 pa = (uint64)kalloc();
        if (pa == 0) {
            panic("memory run out\n");
            return 0;
        }
        if (mappages(p->pagetable, va, PGSIZE, pa, PTE_W | PTE_X | PTE_R | PTE_U) != 0) {
            kfree((void *)pa);
            return 0;
        }
        // *pte = PA2PTE(pa) | PTE_W | PTE_X | PTE_R | PTE_U | PTE_V;
    }

第5点,只要你用了kalloc后判断了它的返回值,然后panic就行

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/85212.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

pandas数据分析40——读取 excel 合并单元格的表头

案例背景 真的很容易疯....上班的单位的表格都是不同的人做的&#xff0c;所以就会出现各种合并单元格的情况&#xff0c;要知道我们用pandas读取数据最怕合并单元格了&#xff0c;因为没规律...可能前几列没合并&#xff0c;后面几列又合并了....而且pandas对于索引很严格&am…

VR数字工厂多元化展现,打造数字企业工厂名片

5G时代&#xff0c;各种营销都在走数字化的路子&#xff0c;VR数字工厂用VR赋能工厂数字升级&#xff0c;将企业环境、工厂生产、产品研发、质检运输等流程&#xff0c;无死角720度的展示在客户面前&#xff0c;不仅可以提升自身企业的实力&#xff0c;还可以提高客户的信任感。…

使用Pandas处理Excel文件

Excel工作表是非常本能和用户友好的&#xff0c;这使得它们非常适合操作大型数据集&#xff0c;即使是技术人员也不例外。如果您正在寻找学习使用Python在Excel文件中操作和自动化内容的地方&#xff0c;请不要再找了。你来对地方了。 在本文中&#xff0c;您将学习如何使用Pan…

超级计算机

超级计算机是一种高性能计算机&#xff0c;它能够以极高的速度执行大规模的计算任务。超级计算机通常由数千个甚至数百万个处理器组成&#xff0c;这些处理器能够同时处理大量的数据&#xff0c;从而实现高效的计算。超级计算机广泛应用于科学、工程、金融、天气预报等领域&…

5G与4G的RRC协议之异同

什么是无线资源控制&#xff08;RRC&#xff09;&#xff1f; 我们知道&#xff0c;在移动通信中&#xff0c;无线资源管理是非常重要的一个环节&#xff0c;首先介绍一下什么是无线资源控制&#xff08;RRC&#xff09;。 手机和网络通过无线信道相互通信&#xff0c;彼此交…

SpringBoot - 两种方式刷新配置信息

一、第一种方式 ​ConfigurationProperties​不能自动刷新&#xff0c;需要手动调用contextRefresher.refresh()方法来刷新配置。 import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component;Component…

C#学习....

1.基础 //引用命名空间using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;//项目名或者命名空间 namespace _01_MY_First_Demo {//Program类class Program{//程序的主入口或者Main函数static void Main(S…

前端开发怎么解决性能优化的问题? - 易智编译EaseEditing

前端性能优化是确保网站或应用在加载速度、响应性和用户体验等方面达到最佳状态的关键任务。以下是一些解决前端性能优化问题的方法&#xff1a; 压缩和合并代码&#xff1a; 压缩和合并CSS、JavaScript和HTML文件可以减少文件大小&#xff0c;加快加载速度。使用压缩工具&am…

分布式核心知识以及常见微服务框架

分布式中的远程调用 在微服务架构中&#xff0c;通常存在多个服务之间的远程调用的需求。远程调用通常包含两个部分&#xff1a;序列化和通信协议。常见的序列化协议包括json、xml、 hession、 protobuf、thrift、text、 bytes等&#xff0c;目前主流的远程调用技术有基于HTTP…

C语言编写图形界面

文章目录 环境使用库基础概念句柄 程序的入口创建窗口定义窗口类注册窗口类创建窗口 完整代码运行效果 环境 使用的是VSCode MinGW&#xff1b; 使用库 我们使用windows.h库来实现图形化界面。 头文件如下&#xff1a; #include <windows.h>windows.h是 Windows 操作…

特斯拉Model 3的七年狂飙

‍ 作者 | 张祥威 编辑 | 德新 发布一周拿下32万张订单&#xff0c;之后用时五年&#xff0c;交付量突破100万辆。粗略计算&#xff0c;自2016年发布至今&#xff0c;特斯拉Model 3已交付超150万辆。 放眼新能源赛道&#xff0c;如此战绩 别无二家。 Model 3踩中纯电动车的…

8.19论文阅读

文章目录 Graph-Segmenter: Graph Transformer with Boundary-aware Attention for Semantic Segmentation方法 SCSC: Spatial Cross-scale Convolution Module to Strengthen both CNNs and Transformers方法 Deformable Mixer Transformer with Gating for Multi-Task Learni…

Kubernetes 使用 Rancher 管理

K8S集群管理工具 只能管理单个K8S集群 kubectl命令行管理工具 dashboard&#xff08;K8S官方的UI界面图形化管理工具&#xff09; &#xff08;管理多集群很麻烦&#xff0c;切换不同集群每次需要更改kube-config文件[kubectl配置文件]&#xff0c;如果kubeadm部署每次都需…

Java动态代理、反射

文章目录 动态代理调用者--->代理--->对象为什么需要代理代理的详细实现过程代码详情 反射反射概念反射中常用的方法所有代码 动态代理 调用者—>代理—>对象 动态代理就是无侵入式的给代码增加新的功能&#xff0c;通过接口保证后面的对象和代理需要实现同一个接…

常用的电参数

电参数根据电流的特点可以分为直流电参数和交流电参数&#xff0c;在电参数中有些是可以通过电参数表测得&#xff0c;有些参数则为通过测得的参数计算而来。 一、电参数 1.1 直接可测电参数 ——瞬时电压值 ——瞬时电流值 n——采样点数 f——频率 time——时间 其中&…

探究Java spring中jdk代理和cglib代理!

面对新鲜事物&#xff0c;我们要先了解在去探索事物的本质-默 目录 一.介绍二者代理模式 1.1.Jdk代理模式 1.2cglib代理模式 1.3二者区别 1.3.1有无接口 1.3.2灵活性 1.4对于两种代理模式的总结 1.4.1jdk代理模式 1.4.2cglib代理模式 二.两种代理模式应用场景 2.1jd…

使用R语言绘制折线图

写在前面 昨天我们分享了使用Python绘制折线图的教程,跟着NC学作图 | 使用python绘制折线图,考虑到很多同学基本不使用Python绘图。那么,我们也使用R语言复现此图形。 此外,在前期的教程中,我们基本没有分享过折线图的教程。因此,我们在这里也制作一期关于折线图的教程。…

Qt 编译使用Bit7z库接口调用7z.dll、7-Zip.dll解压压缩常用Zip、ISO9660、Wim、Esd、7z等格式文件(一)

bit7z一个c静态库&#xff0c;为7-zip共享库提供了一个干净简单的接口 使用CMAKE重新编译github上的bit7z库&#xff0c;用来解压/预览iso9660&#xff0c;WIm&#xff0c;Zip,Rar等常用的压缩文件格式。z-zip库支持大多数压缩文件格式 导读 编译bit7z(C版本)使用mscv 2017编译…

系统架构设计师之缓存技术:Redis持久化的两种方式-RDB和AOF

系统架构设计师之缓存技术&#xff1a;Redis持久化的两种方式-RDB和AOF

无人机空管电台-中大型无人机远程VHF语音电台系统

方案背景 中大型无人机在执行飞行任务时&#xff0c;特别是在管制空域飞行时地面航管人员需要通过语音与无人机通信。按《无人驾驶航空器飞行管理暂行条例》规定&#xff0c;中大型无人机应当进行适航管理。物流无人机和载人eVTOL都将进行适航管理&#xff0c;所以无人机也要有…
最新文章