modify some mistakes.
This commit is contained in:
@@ -381,7 +381,7 @@ _fifo_swap_out_victim(struct mm_struct *mm, struct Page ** ptr_page, int in_tick
|
||||
|
||||
+ 第一次循环寻找`PTE_A == 0 && PTE_D == 0`的页面,并且同时将经过的页面的`PTE_A`赋值为零。如果的确找到这样的页面,则将它作为要换出的页面,从循环链表中删除,并且将指针`sm_priv`移向它的后一个页面。
|
||||
+ 如果第一次循环没找到适合换出的页面,则进行第二次循环,仍然是查找满足`PTE_A == 0 && PTE_D == 0`,后续操作也与第一步相同。
|
||||
+ 如果第二步也失败,直接将当前指针`sm_priv`指向的页面换出。这是因为,此时链表中的所有页面都满足`PTE_A == 0 && PTE_D = 1`,此时只能换出一个修改过的页面。
|
||||
+ 如果第二步也失败,直接将当前指针`sm_priv`指向的页面换出。这是因为,此时链表中的所有页面都满足`PTE_A == 0 && PTE_D == 1`,此时只能换出一个修改过的页面。
|
||||
|
||||
此外,在`swap_out`函数中也要做相应的修改,增加对页面`PTE_D`的判断,只有在`PTE_D = 1`时,才将页面写回到外存当中。将页面换出后,记得要修改页表项相关的标志位。
|
||||
|
||||
|
||||
@@ -223,7 +223,7 @@ copy_range(pde_t *to, pde_t *from, uintptr_t start, uintptr_t end, bool share) {
|
||||
|
||||
### `COW`机制实现
|
||||
|
||||
为了实现`COW`,只需要在`mm_copy`函数中,设置子进程的页表为父进程的一个拷贝,而并不实际为子进程分配这些内存空间。需要注意的是,这与`CLONE_VM`的情形是不同的,`CLONE_VM`是指父子进程共用一个`mm_struct`,当然也共用一个页表;`COW`机制则是子进程拥有自己独立的`mm_struct`,只不过其中的内容是父进程的一个拷贝而已。当父进程或者子进程要写它们共有的内存空间时,就利用`Page Fault`机制,为该进程分配一个新的内存空间,该内存空间时私有而非共享的,并且将要写的页面复制到新分配的内存空间中,这样修改对共享页面的其他进程就都是不可见的了。
|
||||
为了实现`COW`,只需要在`mm_copy`函数中,设置子进程的页表为父进程的一个拷贝,而并不实际为子进程分配这些内存空间。需要注意的是,这与`CLONE_VM`的情形是不同的,`CLONE_VM`是指父子进程共用一个`mm_struct`,当然也共用一个页表;`COW`机制则是子进程拥有自己独立的`mm_struct`,只不过其中的内容是父进程的一个拷贝而已。当父进程或者子进程要写它们共有的内存空间时,就利用`Page Fault`机制,为该进程分配一个新的内存空间,该内存空间是私有而非共享的,并且将要写的页面复制到新分配的内存空间中,这样修改对共享页面的其他进程就都是不可见的了。
|
||||
|
||||
上面说的很简单,但是实现起来还要考虑一些复杂的问题,比如如果共享页面被换出到外存当中,如何在共享该页面的所有进程的页表中,也修改它的状态为`换出`;此外,写操作时触发`Page Fault`具体又是如何实现的呢?在`Page Fault`中就如何判断触发原因是`COW`呢?
|
||||
|
||||
|
||||
Reference in New Issue
Block a user