Copy on Write實現
阿新 • • 發佈:2021-11-19
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狀態,需要將目標頁的內容複製到新的頁中。