Copy on Write实现
Posted zhushoucheng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Copy on Write实现相关的知识,希望对你有一定的参考价值。
xv6中并没有实现这个部分,我自己实现的COW代码没有保存,因此借用了别人的代码,主要是了解实现方法。
COW(copy on write)指fork复制子进程时,并不直接复制父进程的内存内容至子进程中(因为开销很大),而是将这些内存的一个特殊COW标志置1。因此,子进程读内存时,实际上是读的父进程的内存。当子进程或者父进程需要写内存时,操作系统将使用缺页中断将涉及的内存页表单独复制。即将内存复制的过程延后,并且仅处理使用到的内存部分,可以极大的节约资源消耗。
- 首先创建int refNum[32768],用来记录每个物理页的实际关联数,即子进程复制父进程页时,只是对refNum中对应的物理页做+1操作
-
在页表项中新增PTE_COW标志位。
- 修改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;
}
-
修改中断处理函数usertrap。缺页中断会使scause寄存器置为13,可以借此判断中断类型。
缺页中断的目标地址存储在stval寄存器中,使用walk函数通过页表获得该虚拟地址对应的物理页的pte
判断pte的refNum关联数,如果等于2,说明该页不再处于COW状态,将COW标志去除,write标志打开,表明可以对该内存页进行写操作
如果大于2,说明该页处于COW状态,需要将目标页的内容复制到新的页中。
以上是关于Copy on Write实现的主要内容,如果未能解决你的问题,请参考以下文章
C++:Copy-On-Write技术以及string类的模拟实现
MongoDB Wiredtiger存储引擎实现原理——Copy on write的方式管理修改操作,Btree cache