MIT xv6 design from user prespective
I will use mit 6.s801 lab1 “util” as an entry to the code behind. This article will not talk much about how to do lab1, but reveal some delicate design behind the syscall lab1 use.
ex1- sleep
#easy
This is the easiest lab in the lab1, so I will not talk about this exercise. Let’s go through the syscall sys_sleep
in sysproc.c
uint64
sys_sleep(void)
{
int n;
uint ticks0;
if(argint(0, &n) < 0)
return -1;
acquire(&tickslock);
ticks0 = ticks; // ticks is a golbal var maintained by trap
while(ticks - ticks0 < n){
if(myproc()->killed){
release(&tickslock);
return -1;
}
sleep(&ticks, &tickslock);
}
release(&tickslock);
return 0;
}
-
ticks
is the global variable maintained intrap.c
, when a time interrupt occurs(1 ms) , thedevintr()
intrap.c
will add upticks
.ticks
is protected bytickslock
.clockintr() { acquire(&tickslock); ticks++; wakeup(&ticks); release(&tickslock); }
-
sleep()
in kernel, take 2 vars, the first one is the condition variable( akachan
variable ), which is saved in the proc’s PCB, the next one is the lock that will be release before sleep.struct proc { ... void *chan; // If non-zero, sleeping on chan ... ... };
-
everytime
ticks
++ inclockintr()
, it willwakeup()
all sleeping process holdingticks
in itschan
void wakeup(void *chan) { struct proc *p; for(p = proc; p < &proc[NPROC]; p++) { acquire(&p->lock); if(p->state == SLEEPING && p->chan == chan) { p->state = RUNNABLE; } release(&p->lock); } }
ex2- pingpong
#easy
another easy lab, in this section I will dive in the syscall sys_pipe()
read()
, write()
, and try to answer why the pipe need be in one direction while using.
uint64
sys_pipe(void)
{
uint64 fdarray; // user pointer to array of two integers
struct file *rf, *wf;
int fd0, fd1;
struct proc *p = myproc();
if(argaddr(0, &fdarray) < 0)
return -1;
if(pipealloc(&rf, &wf) < 0)
return -1;
fd0 = -1;
if((fd0 = fdalloc(rf)) < 0 || (fd1 = fdalloc(wf)) < 0){
if(fd0 >= 0)
p->ofile[fd0] = 0;
fileclose(rf);
fileclose(wf);
return -1;
}
if(copyout(p->pagetable, fdarray, (char*)&fd0, sizeof(fd0)) < 0 ||
copyout(p->pagetable, fdarray+sizeof(fd0), (char *)&fd1, sizeof(fd1)) < 0){
p->ofile[fd0] = 0;
p->ofile[fd1] = 0;
fileclose(rf);
fileclose(wf);
return -1;
}
return 0;
}
- File system
ex4/5 find and xargs
#mid I will talk about the directory layer and inode layer of the xv6 File system
ex3 primes
#hard
Dive in fork()
, and the basic design of “ex3 primes”.