多用户环境调度(续).ppt
文本预览下载声明
第六章. 系统调度,COW Fork和IPC(lab4) 提纲 多用户环境调度 COW Fork (写时拷贝环境创建) 用户环境间通讯(IPC) 多用户环境调度 Idle 环境及yield RR (Round-Robin) Scheduling 子进程的创建(Dumb Fork) 多用户环境调度(续) Idle 用户环境 #include inc/x86.h #include inc/lib.h void umain(void) { binaryname = idle; while (1) { sys_yield(); breakpoint(); } } 多用户环境调度(续) sys_yield的执行路线 多用户环境调度(续) yield 放弃本用户环境的执行 选择“适当”的用户环境投入运行 “适当”应该根据具体的调度算法进行 多用户环境调度(续) RR (Round-Robin) Scheduling 循环轮转算法 应该寻找除了释放CPU的当前用户环境(curenv)和idle用户环境之外的“下一个”用户环境投入运行(采用env_run),在找不到的情况下将idle用户环境投入运行(breakpoint)。 由于idle用户环境占据了envs[0],应该在envs[1]到envs[NENV-1]之间寻找“下一个”用户环境。 完成sched_yield(void)函数 多用户环境调度(续) 子进程的创建(Dumb Fork) 完成sys_exofork(void)函数 分配用户环境管理数据结构 将创建的子环境的上下文设置为当前用户环境的上下文 设置创建的子环境的状态为ENV_NOT_RUNNABLE 完成空间分配和映射等辅助函数 sys_env_set_status (设置状态) sys_page_alloc (为用户态环境分配页面) sys_page_map (建立页面的映射关系) sys_page_unmap (取消页面的映射关系) 多用户环境调度(续) Dumb Fork (user/dumbfork.c) 思考: 如何让父环境在调用sys_exofork( ) 后返回子环境的envid,而子环境返回0? 如何通过页面分配和拷贝实现子用户环境的运行? UTEMP的作用是什么?这里能不能用UTOP? 修改kern/init.c运行dumbfork.c COW Fork COW的概念 User Trap Frame的设置 用户态页面失效处理 Fork COW Fork(续) COW的概念 在dumb fork中,JOS采用的是全拷贝的方法(从UTEXT到end)来运行子环境 然而通过复制父环境的方法来提供子环境的运行上下文会是相当重负载的 特别是当子环境创建后,需要加载不同于父环境的代码和数据开始运行的情况(如通过Shell的exec创建的子环境) 考虑三种类型的段:代码段、数据段(包括附加数据段)、堆栈段。其中代码段是完全不需要拷贝的,只需要映射即可。 采用写时复制技术(即当有数据更新的时候才复制整个被写的页面)来完成子环境的创建 COW Fork(续) COW的概念(续) 因为写时复用技术的采用,就需要对子环境对页面的写操作进行截获 完成这项工作,最简单的办法就是利用缺页中断 JOS中采用的是用户级缺页中断处理的方法 在子环境的管理数据结构中定义回调函数env_pgfault_upcall,用户环境通过调用sys_env_set_pgfault_upcall系统调用来设置自己的缺页中断处理函数,并让内核态的中断处理过程调用被登记的中断处理函数。 思考:JOS采用这种用户级的缺页处理方法的优缺点是什么? COW Fork(续) User Trap Frame的设置 思考: 1. 为什么要设置User Trap Frame? 2. 如何设置User Trap Frame,为什么要通过这样的办法来设置? 3. 如何判断是不是nested page fault 4. 当从内核态回到用户态的时候,如何跳到用户态的页面失效处理函数入口? 完成: lib/pgfault.c的set_pgfault_handler( void (*handler)(struct UTrapframe *utf)) kern/syscall.c的 sys_env_set_pgfault_upcall (envid_t envid, void *func) kern/trap.c的page_fault_handler (struct Trapframe *tf) COW Fork(续) 用户态页面失效处理 注意:用户态页面失效处理过程
显示全部