diff --git a/kernel/proc.c b/kernel/proc.c index 54c965d..bd77dad 100644 --- a/kernel/proc.c +++ b/kernel/proc.c @@ -358,14 +358,14 @@ exit(int status) p->cwd = 0; acquire(&proc_tree_lock); - - acquire(&p->lock); // Give any children to init. reparent(p); // Parent might be sleeping in wait(). wakeup(p->parent); + + acquire(&p->lock); p->xstate = status; p->state = ZOMBIE; @@ -393,7 +393,9 @@ wait(uint64 addr) havekids = 0; for(np = proc; np < &proc[NPROC]; np++){ if(np->parent == p){ + // make sure the child isn't still in exit() or swtch(). acquire(&np->lock); + havekids = 1; if(np->state == ZOMBIE){ // Found one. diff --git a/kernel/proc.h b/kernel/proc.h index e86bde1..8e90008 100644 --- a/kernel/proc.h +++ b/kernel/proc.h @@ -88,12 +88,14 @@ struct proc { // p->lock must be held when using these: enum procstate state; // Process state - struct proc *parent; // Parent process void *chan; // If non-zero, sleeping on chan int killed; // If non-zero, have been killed int xstate; // Exit status to be returned to parent's wait int pid; // Process ID + // proc_tree_lock must be held when using this: + struct proc *parent; // Parent process + // these are private to the process, so p->lock need not be held. uint64 kstack; // Virtual address of kernel stack uint64 sz; // Size of process memory (bytes)