本文记录MIT-OS6.S081 Lab5 lazy page allocation 的Eliminate allocation from sbrk()函数的实现过程
文章目录
- [1. 作业要求](#1. 作业要求)
-
- [Eliminate allocation from sbrk() (easy)](#Eliminate allocation from sbrk() (easy))
- [2. 实现过程](#2. 实现过程)
-
- [2.1 代码实现](#2.1 代码实现)
1. 作业要求
Eliminate allocation from sbrk() (easy)
Your first task is to delete page allocation from the sbrk(n) system call implementation, which is the function sys_sbrk() in sysproc.c. The sbrk(n) system call grows the process's memory size by n bytes, and then returns the start of the newly allocated region (i.e., the old size). Your new sbrk(n) should just increment the process's size (myproc()->sz) by n and return the old size. It should not allocate memory -- so you should delete the call to growproc() (but you still need to increase the process's size!).
Try to guess what the result of this modification will be: what will break?
Make this modification, boot xv6, and type
echo hito the shell. You should see something like this:
c
init: starting sh
$ echo hi
usertrap(): unexpected scause 0x000000000000000f pid=3
sepc=0x0000000000001258 stval=0x0000000000004008
va=0x0000000000004000 pte=0x0000000000000000
panic: uvmunmap: not mapped
- The "usertrap(): ..." message is from the user trap handler in trap.c; it has caught an exception that it does not know how to handle. Make sure you understand why this page fault occurs. The "stval=0x0...04008" indicates that the virtual address that caused the page fault is 0x4008.
2. 实现过程
2.1 代码实现
Your new sbrk(n) should just increment the process's size (myproc()->sz) by n and return the old size. It should not allocate memory -- so you should delete the call to growproc() (but you still need to increase the process's size!).
这个提示的意思是只增加进程的sz,返回旧的size,但是不分配内存。
我们看一下原来的sys_sbrk函数,调用了growproc函数来对内存进行重新分配,返回旧的大小。
c
uint64
sys_sbrk(void)
{
int addr;
int n;
if(argint(0, &n) < 0)
return -1;
addr = myproc()->sz;
if(growproc(n) < 0)
return -1;
return addr;
}
进入growproc:
c
int
growproc(int n)
{
uint sz;
struct proc *p = myproc();
sz = p->sz;
if(n > 0){
if((sz = uvmalloc(p->pagetable, sz, sz + n)) == 0) {
return -1;
}
} else if(n < 0){
sz = uvmdealloc(p->pagetable, sz, sz + n);
}
p->sz = sz;
return 0;
}
uvmalloc底层会调用kalloc函数来分配内存。仿照growproc的思路我们重写一下sys_sbrk:
c
uint64
sys_sbrk(void)
{
uint64 oldSize;
int n;
if(argint(0, &n) < 0)
return -1;
struct proc *p = myproc();
oldSize = p->sz;
if(n > 0){
p->sz += n;
} else if(n < 0){
p->sz = uvmdealloc(p->pagetable, p->sz, p->sz + n);
}
return oldSize;
}
编译通过,测试echo hi,如题打印:

完活!还有bug下一节继续讲怎么实现Lazy allocation。