summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Morris <[email protected]>2019-07-10 10:13:08 -0400
committerRobert Morris <[email protected]>2019-07-10 10:13:08 -0400
commit061e3be6f89cc0b7479fc2bba8b1348f7a9d070d (patch)
treefc12e123dced2b8b242009e40fa8d2fc61a7bd71
parentc0266a877a25fdc0d73016bc7e7bf0f1800b3e0e (diff)
downloadxv6-labs-061e3be6f89cc0b7479fc2bba8b1348f7a9d070d.tar.gz
xv6-labs-061e3be6f89cc0b7479fc2bba8b1348f7a9d070d.tar.bz2
xv6-labs-061e3be6f89cc0b7479fc2bba8b1348f7a9d070d.zip
more comment cleanup
-rw-r--r--kernel/proc.c54
1 files changed, 30 insertions, 24 deletions
diff --git a/kernel/proc.c b/kernel/proc.c
index 1c222d3..46ac128 100644
--- a/kernel/proc.c
+++ b/kernel/proc.c
@@ -73,7 +73,7 @@ allocpid() {
// Look in the process table for an UNUSED proc.
// If found, initialize state required to run in the kernel,
// and return with p->lock held.
-// Otherwise return 0.
+// If there are no free procs, return 0.
static struct proc*
allocproc(void)
{
@@ -94,6 +94,7 @@ found:
// Allocate a page for the kernel stack.
if((p->kstack = kalloc()) == 0){
+ release(&p->lock);
return 0;
}
@@ -101,6 +102,7 @@ found:
if((p->tf = (struct trapframe *)kalloc()) == 0){
kfree(p->kstack);
p->kstack = 0;
+ release(&p->lock);
return 0;
}
@@ -141,16 +143,13 @@ freeproc(struct proc *p)
}
// Create a page table for a given process,
-// with no users pages, but with trampoline pages.
-// Called both when creating a process, and
-// by exec() when building tentative new memory image,
-// which might fail.
+// with no user pages, but with trampoline pages.
pagetable_t
proc_pagetable(struct proc *p)
{
pagetable_t pagetable;
- // An empty user page table.
+ // An empty page table.
pagetable = uvmcreate();
// map the trampoline code (for system call return)
@@ -168,9 +167,7 @@ proc_pagetable(struct proc *p)
}
// Free a process's page table, and free the
-// physical memory the page table refers to.
-// Called both when a process exits and from
-// exec() if it fails.
+// physical memory it refers to.
void
proc_freepagetable(pagetable_t pagetable, uint64 sz)
{
@@ -183,9 +180,12 @@ proc_freepagetable(pagetable_t pagetable, uint64 sz)
// a user program that calls exec("/init")
// od -t xC initcode
uchar initcode[] = {
- 0x17, 0x05, 0x00, 0x00, 0x13, 0x05, 0x05, 0x02, 0x97, 0x05, 0x00, 0x00, 0x93, 0x85, 0x05, 0x02,
- 0x9d, 0x48, 0x73, 0x00, 0x00, 0x00, 0x89, 0x48, 0x73, 0x00, 0x00, 0x00, 0xef, 0xf0, 0xbf, 0xff,
- 0x2f, 0x69, 0x6e, 0x69, 0x74, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x17, 0x05, 0x00, 0x00, 0x13, 0x05, 0x05, 0x02,
+ 0x97, 0x05, 0x00, 0x00, 0x93, 0x85, 0x05, 0x02,
+ 0x9d, 0x48, 0x73, 0x00, 0x00, 0x00, 0x89, 0x48,
+ 0x73, 0x00, 0x00, 0x00, 0xef, 0xf0, 0xbf, 0xff,
+ 0x2f, 0x69, 0x6e, 0x69, 0x74, 0x00, 0x00, 0x01,
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00
};
@@ -199,12 +199,14 @@ userinit(void)
p = allocproc();
initproc = p;
+ // allocate one user page and copy init's instructions
+ // and data into it.
uvminit(p->pagetable, initcode, sizeof(initcode));
p->sz = PGSIZE;
// prepare for the very first "return" from kernel to user.
- p->tf->epc = 0;
- p->tf->sp = PGSIZE;
+ p->tf->epc = 0; // user program counter
+ p->tf->sp = PGSIZE; // user stack pointer
safestrcpy(p->name, "initcode", sizeof(p->name));
p->cwd = namei("/");
@@ -214,7 +216,7 @@ userinit(void)
release(&p->lock);
}
-// Grow current process's memory by n bytes.
+// Grow or shrink user memory by n bytes.
// Return 0 on success, -1 on failure.
int
growproc(int n)
@@ -236,8 +238,8 @@ growproc(int n)
return 0;
}
-// Create a new process, copying p as the parent.
-// Sets up child kernel stack to return as if from system call.
+// Create a new process, copying the parent.
+// Sets up child kernel stack to return as if from fork() system call.
int
fork(void)
{
@@ -308,7 +310,6 @@ reparent(struct proc *p, struct proc *parent) {
}
}
-
// Exit the current process. Does not return.
// An exited process remains in the zombie state
// until its parent calls wait().
@@ -339,6 +340,7 @@ exit(void)
acquire(&p->lock);
+ // Give our children to init.
reparent(p, p->parent);
p->state = ZOMBIE;
@@ -362,7 +364,10 @@ wait(void)
int havekids, pid;
struct proc *p = myproc();
+ // hold p->lock for the whole time to avoid lost
+ // wakeups from a child's exit().
acquire(&p->lock);
+
for(;;){
// Scan through table looking for exited children.
havekids = 0;
@@ -371,8 +376,8 @@ wait(void)
// acquiring the lock first would cause a deadlock,
// since np might be an ancestor, and we already hold p->lock.
if(np->parent == p){
- // np->parent can't change here because only the parent
- // changes it, and we're the parent.
+ // np->parent can't change between the check and the acquire()
+ // because only the parent changes it, and we're the parent.
acquire(&np->lock);
havekids = 1;
if(np->state == ZOMBIE){
@@ -393,7 +398,7 @@ wait(void)
return -1;
}
- // Wait for children to exit. (See wakeup1 call in reparent.)
+ // Wait for a child to exit.
sleep(p, &p->lock); //DOC: wait-sleep
}
}
@@ -436,7 +441,7 @@ scheduler(void)
}
}
-// Enter scheduler. Must hold only p->lock
+// Switch to scheduler. Must hold only p->lock
// and have changed proc->state. Saves and restores
// intena because intena is a property of this
// kernel thread, not this CPU. It should
@@ -519,6 +524,7 @@ sleep(void *chan, struct spinlock *lk)
acquire(&p->lock); //DOC: sleeplock1
release(lk);
}
+
// Go to sleep.
p->chan = chan;
p->state = SLEEPING;
@@ -536,7 +542,7 @@ sleep(void *chan, struct spinlock *lk)
}
//PAGEBREAK!
-// Wake up p, used by exit()
+// Wake up p, used by exit().
// Caller must hold p->lock.
static void
wakeup1(struct proc *p)
@@ -563,7 +569,7 @@ wakeup(void *chan)
}
// Kill the process with the given pid.
-// Process won't exit until it returns
+// The victim won't exit until it tries to return
// to user space (see usertrap() in trap.c).
int
kill(int pid)