Copy on Write实现

2021年11月20日 阅读数:3
这篇文章主要向大家介绍Copy on Write实现,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

xv6中并无实现这个部分,我本身实现的COW代码没有保存,所以借用了别人的代码,主要是了解实现方法。app

COW(copy on write)指fork复制子进程时,并不直接复制父进程的内存内容至子进程中(由于开销很大),而是将这些内存的一个特殊COW标志置1。所以,子进程读内存时,其实是读的父进程的内存。当子进程或者父进程须要写内存时,操做系统将使用缺页中断将涉及的内存页表单独复制。即将内存复制的过程延后,而且仅处理使用到的内存部分,能够极大的节约资源消耗。函数

  1. 首先建立int refNum[32768],用来记录每一个物理页的实际关联数,即子进程复制父进程页时,只是对refNum中对应的物理页作+1操做
在这里插入图片描述
  1. 在页表项中新增PTE_COW标志位。ui

    在这里插入图片描述

img
  1. 修改fork函数中的uvmcopy()函数(该函数用于复制父进程内存到子进程),不复制内存,而改成将物理页的对应refNum+1
在这里插入图片描述

下面是原代码,对比一下便可发现再也不调用memmove函数了操作系统

    pa = PTE2PA(*pte);
    flags = PTE_FLAGS(*pte);
    if((mem = kalloc()) == 0)
      goto err;
    memmove(mem, (char*)pa, PGSIZE);
    if(mappages(new, i, PGSIZE, (uint64)mem, flags) != 0){
      kfree(mem);
      goto err;
    }
在这里插入图片描述
  1. 修改中断处理函数usertrap。缺页中断会使scause寄存器置为13,能够借此判断中断类型。code

    缺页中断的目标地址存储在stval寄存器中,使用walk函数经过页表得到该虚拟地址对应的物理页的pteblog

    判断pte的refNum关联数,若是等于2,说明该页再也不处于COW状态,将COW标志去除,write标志打开,代表能够对该内存页进行写操做进程

    若是大于2,说明该页处于COW状态,须要将目标页的内容复制到新的页中。图片

在这里插入图片描述