`
talin2010
  • 浏览: 522430 次
  • 性别: Icon_minigender_1
  • 来自: 河北
社区版块
存档分类
最新评论

[MIT6.828] LAB4 Part B: Copy-on-Write Fork

阅读更多

Exercise 3. Implement the sys_env_set_pgfault_upcall system call. Be sure to enable permission checking when looking up the environment ID of the target environment, since this is a "dangerous" system call.

修改kern/syscall.c文件,添加注册页故障处理函数的功能:
1、修改sys_env_set_pgfault_upcall()函数

在代码中有两行被注释掉了,刚开始的时候我是用这两行代码检测传入的func是否合法,但是评分程序过不了才知道这里不要求验证func的有效性。不过我还是觉得在这里验证最好,毕竟往内核传入指针了阿。

2、修改syscal函数,把sys_env_set_pgfault_upcall()注册给适当的调用号。

Exercise 4. Implement the code in page_fault_handler in kern/trap.c required to dispatch page faults to the user-mode handler. Be sure to take appropriate precautions when writing into the exception stack. (What happens if the user environment runs out of space on the exception stack?)


修改kern/trap.c,在异常处理中加入调用用户注册的页错误处理函数的功能

注意检查用户页错误处理函数是否注册,用户异常栈是否分配,是否溢出,是否页错误嵌套。并注意给新的UTrapframe和嵌套返回值保留空间。

Exercise 5. Implement the _pgfault_upcall routine in lib/pfentry.S. The interesting part is returning to the original point in the user code that caused the page fault. You'll return directly there, without going back through the kernel. The hard part is simultaneously switching stacks and re-loading the EIP.

修改lib/pfentry.S文件,在用户层加入用户页错误处理函数的入口功能。

step 0是调用用户注册的用户页错误处理函数。step 1 是用来设置返回到发生页错误(原始)的地址。 step 2是用来弹出通用寄存器。 step 3 是用来弹出状态寄存器。 step 4用来切换esp到原始栈。 step 5就是返回到原始地址。
各种注意事项代码的注释中已有说明,一定得认真看了再去写代码。


Exercise 6. Finish set_pgfault_handler() in lib/pgfault.c.

修改lib/pgfault.c文件的set_pgfault_handler()函数

注意这里饶了个弯子,没有直接注册handler而是注册了练习5中的汇编函数_pgfault_upcall,这样是因为要从handler直接返回到用户页错误发生处,需要汇编函数_pgfault_upcall来制造栈环境(普通C代码无能为力)。

Challenge! Extend your kernel so that not only page faults, but all types of processor exceptions that code running in user space can generate, can be redirected to a user-mode exception handler. Write user-mode test programs to test user-mode handling of various exceptions such as divide-by-zero, general protection fault, and illegal opcode.

给系统异常加入注册用户异常处理函数的系统调用。这个最简单的实现方法是只写一个系统调用,用参数中的异常号来分辨不同的异常,代码可以精简很多。如果觉得这样写用户调用不方便(还得记异常号)那就给每个异常写一个用户层的lib接口。这样还可以保持上面写的set_pgfault_handler函数不动。 没啥技术含量和挑战性,咱就不写了,以后有机会再说。

Exercise 7. Implement fork, duppage and pgfault in lib/fork.c.
Test your code with the forktree program. It should produce the following messages, with interspersed 'new env', 'free env', and 'exiting gracefully' messages. The messages may not appear in this order, and the environment IDs may be different.

修改lib/fork.c文件

pgfault()函数:检查页属性,然后分配页,复制数据。

duppage()函数:注意区别写/写时复制 和 只读页面。在这里想到,其实在kern/env.c的load_inode()函数里面我们都是用可写的方式处理页面。所以需要注意改进阿。

fork()函数:这里需要注意,由于新建进程时,自进程会把自己的pgfault_handler设置成空,所以要重新注册一下。
不过不能在子进程注册,因为运行子进程时候调用函数或者写入变量会导致页错误,这时候还没有注册pgfault_handler,所以就默认进程销毁了。 只能在父进程设置子进程的句柄。我有个疑问,为什么不在新建进程的时候直接把pgfault_handler继承过来呢,不知道设计者怎么想的。


Challenge! Implement a shared-memory fork() called sfork(). This version should have the parent and child share all their memory pages (so writes in one environment appear in the other) except for pages in the stack area, which should be treated in the usual copy-on-write manner. Modify user/forktree.c to use sfork() instead of regular fork(). Also, once you have finished implementing IPC in part C, use your sfork() to run user/pingpongs. You will have to find a new way to provide the functionality of the global env pointer.

修改lib/fork.c。把sfork()函数变成一个读写共享全局数据和代码的fork()

和fork()函数基本一致,只需要注意共享UTEXT到end之间的数据时老老实实的按照原来的属性重新映射一个到子进程就可以了,注意权限哦

Challenge! Your implementation of fork makes a huge number of system calls. On the x86, switching into the kernel using interrupts has non-trivial cost. Augment the system call interface so that it is possible to send a batch of system calls at once. Then change fork to use this interface.

How much faster is your new fork?

You can answer this (roughly) by using analytical arguments to estimate how much of an improvement batching system calls will make to the performance of your fork: How expensive is an int 0x30 instruction? How many times do you execute int 0x30 in your fork? Is accessing the TSS stack switch also expensive? And so on...

Alternatively, you can boot your kernel on real hardware and really benchmark your code. See the RDTSC (read time-stamp counter) instruction, defined in the IA32 manual, which counts the number of clock cycles that have elapsed since the last processor reset. QEMU doesn't emulate this instruction faithfully (it can either count the number of virtual instructions executed or use the host TSC, neither of which reflects the number of cycles a real CPU would require).

这次的挑战是要求测试下fork的速度,可以通过RDTSC指令阿或者指令计数器来计算。这次的fork调用了N多个系统调用,每个系统调用都要切换栈空间,压入弹出N多寄存器,尤其是后来我还加入了浮点寄存器的保护,这都512个字节呢。速度会奇慢无比,具体代码不写了。RDTSC指令格式满大街都是,大家自己google吧。

分享到:
评论

相关推荐

    MIT6.828 lab4 实验报告

    在MIT6.828的lab4实验报告中,核心知识点包括多处理器支持、协作式多任务处理、内存映射输入输出、应用处理器(AP)引导程序、CPU私有状态与初始化、大内核锁、轮转调度算法、创建其他进程的系统调用、写时复制...

    eclipse-collections-forkjoin-7.1.2-API文档-中文版.zip

    赠送jar包:eclipse-collections-forkjoin-7.1.2.jar; 赠送原API文档:eclipse-collections-forkjoin-7.1.2-javadoc.jar; 赠送源代码:eclipse-collections-forkjoin-7.1.2-sources.jar; 赠送Maven依赖信息文件:...

    https://github.com/PlayVoice/so-vits-svc 预训练文件

    https://github.com/PlayVoice/so-vits-svc 预训练文件

    eclipse-collections-forkjoin-7.1.2-API文档-中英对照版.zip

    赠送jar包:eclipse-collections-forkjoin-7.1.2.jar; 赠送原API文档:eclipse-collections-forkjoin-7.1.2-javadoc.jar; 赠送源代码:eclipse-collections-forkjoin-7.1.2-sources.jar; 赠送Maven依赖信息文件:...

    org.eclipse.egit.repository-5.5.0.201909110433-r.zip

    - **工作流支持**:支持各种Git工作流,如Fork & Pull Request,便于团队协作。 - **历史查看**:可以查看代码的历史版本,追踪代码变更。 - **差异对比**:直观地展示代码之间的差异,便于理解变更内容。 2. ...

    Python库 | pyppeteer_fork-0.0.26-py2.py3-none-any.whl

    资源分类:Python库 所属语言:Python 资源全名:pyppeteer_fork-0.0.26-py2.py3-none-any.whl 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059

    ethminer-0.16.0.dev3

    Apparently about 4MH/s can still be reached on Linux, which, depending on ETH price, could still be profitable, considering the relatively low power draw. For Maxwell 2 GPUs: There is a way of ...

    Mac版本:jdk-8u202-macosx-x64.dmg.zip

    4. ** 流(Stream)**:流API为处理集合提供了一种声明式的方式,特别适合进行数据并行处理,增强了Java对大数据处理的能力。 5. **日期和时间API**:全新的java.time包取代了过时的java.util.Date和java.util....

    Failed to execute goal org...的解决办法

    <fork>true</fork> ${JAVA8_HOME}/bin/javac ``` 3. 环境变量JAVA8_HOME的配置与使用 环境变量JAVA8_HOME用于在Maven配置中指示JDK的安装路径。在settings.xml文件中设置该变量,并在pom.xml中通过占位符引用它...

    MIT6.828课程实验以及源码

    《MIT6.828操作系统课程实验与源码解析》 MIT6.828是麻省理工学院(MIT)开设的一门高级操作系统课程,它深入探讨了操作系统的设计与实现,为学生提供了丰富的实践机会。这门课程的核心部分是实验,通过实际编写和...

    java-7-openjdk-amd64.tar.gz

    1. **多线程改进**:例如,引入了Fork/Join框架,可以更高效地处理并行任务。 2. **动态类型语言支持**:加入了 invokedynamic 字节码指令,支持Clojure、Groovy等动态语言。 3. **字符串改进**:字符串去除了共享...

    jquery.ad-gallery-5-fork-0.1.js:ad-gallery 最初由 Anders Ekdahl 设计,并修复了错误

    《jQuery.ad-gallery-5-fork-0.1.js:Anders Ekdahl的创新与修复的艺术》 在JavaScript的世界里,jQuery库以其简洁的语法和强大的功能深受开发者喜爱。而当我们谈论jQuery的扩展插件时,`jquery.ad-gallery-5-fork-...

    java-1.8.0-openjdk-headless-1.8.0.312.b07-2.el8_5.x86_64.rpm

    离线安装包,亲测可用

    Python库 | librabbitmq_fork-2.0.1.dev2-py3.6-linux-x86_64.egg

    python库。 资源全名:librabbitmq_fork-2.0.1.dev2-py3.6-linux-x86_64.egg

    新概念英语BUnit单元PPT课件.pptx

    - **put…on**:把……放在……上,如“Put the knife on the table.” - **Pass sb sth=pass sth to sb.**:递给某人某物,如“Pass me a knife, please.” - **名词复数变化**:例如单数名词`knife`变为复数`...

    2016九年级英语全册Unit5Whataretheshirtsmadeof练习1新版人教新目标版

    - fork:叉子 - leaf:叶子 - produce:生产 - mobile:可移动的 - for:对...有益 - agree with:同意某人的观点 - be made from/of:由...制成("from"用于原材料不易看出,"of"用于原材料可见) - be ...

    基于 ChatGPT的网页应用实例源码+项目说明(一键部署).zip

    【资源说明】 1、该资源包括项目的全部源码,下载可以直接使用! 2、本项目适合作为计算机、数学、电子信息等专业的课程设计、期末大...当你 fork 项目之后,由于 Github 的限制,需要手动去你 fork 后的项目的 Action

    jdk-8u60-linux-x64.tar.gz

    4. **默认方法**:在接口中添加了默认方法,使得接口可以拥有实现,不强制实现类重写所有方法,增强了对多继承的支持。 5. **日期和时间API**:JDK 8引入了java.time包,替换了原有的日期和时间API,提供了更加友好...

Global site tag (gtag.js) - Google Analytics