根据源代码中的注释,deallocate会释放用户页面,以将进程大小从oldsz变为newsz
我的问题是当PTE不存在时,它应该继续搜索下一页目录条目,但是为什么PGADDR(PDX(A)+ 1, 0, 0)应该减去PGSIZE。
if(!pte)
a = PGADDR(PDX(a) + 1, 0, 0) - PGSIZE;
以下是Xv6的源代码:
int
deallocuvm(pde_t *pgdir, uint oldsz, uint newsz)
{
pte_t *pte;
uint a, pa;
if(newsz >= oldsz)
return oldsz;
a = PGROUNDUP(newsz);
for(; a < oldsz; a += PGSIZE){
pte = walkpgdir(pgdir, (char*)a, 0);
// pte not exists to next page table dir
// do not understand why should minus PGSIZE
if(!pte)
a = PGADDR(PDX(a) + 1, 0, 0) - PGSIZE;
// pte exists
else if((*pte & PTE_P) != 0){
pa = PTE_ADDR(*pte);
if(pa == 0)
panic("kfree");
char *v = P2V(pa);
kfree(v);
*pte = 0;
}
}
return newsz;
}
最佳答案
for
循环确实a += PGSIZE
。每次循环迭代它都会这样做。
如果在进行下一次PDE时没有减去PGSIZE
,那么a
将在下一次迭代中被PGSIZE
元素关闭。