diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/proc.c | 29 | 
1 files changed, 15 insertions, 14 deletions
| diff --git a/kernel/proc.c b/kernel/proc.c index bd77dad..22e7ce4 100644 --- a/kernel/proc.c +++ b/kernel/proc.c @@ -20,10 +20,11 @@ static void freeproc(struct proc *p);  extern char trampoline[]; // trampoline.S -// protects parent/child relationships. -// must be held when using p->parent. +// helps ensure that wakeups of wait()ing +// parents are not lost. helps obey the +// memory model when using p->parent.  // must be acquired before any p->lock. -struct spinlock proc_tree_lock; +struct spinlock wait_lock;  // Allocate a page for each process's kernel stack.  // Map it high in memory, followed by an invalid @@ -48,7 +49,7 @@ procinit(void)    struct proc *p;    initlock(&pid_lock, "nextpid"); -  initlock(&proc_tree_lock, "proc_tree"); +  initlock(&wait_lock, "wait_lock");    for(p = proc; p < &proc[NPROC]; p++) {        initlock(&p->lock, "proc");        p->kstack = KSTACK((int) (p - proc)); @@ -306,9 +307,9 @@ fork(void)    release(&np->lock); -  acquire(&proc_tree_lock); +  acquire(&wait_lock);    np->parent = p; -  release(&proc_tree_lock); +  release(&wait_lock);    acquire(&np->lock);    np->state = RUNNABLE; @@ -318,7 +319,7 @@ fork(void)  }  // Pass p's abandoned children to init. -// Caller must hold proc_tree_lock. +// Caller must hold wait_lock.  void  reparent(struct proc *p)  { @@ -357,7 +358,7 @@ exit(int status)    end_op();    p->cwd = 0; -  acquire(&proc_tree_lock); +  acquire(&wait_lock);    // Give any children to init.    reparent(p); @@ -370,7 +371,7 @@ exit(int status)    p->xstate = status;    p->state = ZOMBIE; -  release(&proc_tree_lock); +  release(&wait_lock);    // Jump into the scheduler, never to return.    sched(); @@ -386,7 +387,7 @@ wait(uint64 addr)    int havekids, pid;    struct proc *p = myproc(); -  acquire(&proc_tree_lock); +  acquire(&wait_lock);    for(;;){      // Scan through table looking for exited children. @@ -403,12 +404,12 @@ wait(uint64 addr)            if(addr != 0 && copyout(p->pagetable, addr, (char *)&np->xstate,                                    sizeof(np->xstate)) < 0) {              release(&np->lock); -            release(&proc_tree_lock); +            release(&wait_lock);              return -1;            }            freeproc(np);            release(&np->lock); -          release(&proc_tree_lock); +          release(&wait_lock);            return pid;          }          release(&np->lock); @@ -417,12 +418,12 @@ wait(uint64 addr)      // No point waiting if we don't have any children.      if(!havekids || p->killed){ -      release(&proc_tree_lock); +      release(&wait_lock);        return -1;      }      // Wait for a child to exit. -    sleep(p, &proc_tree_lock);  //DOC: wait-sleep +    sleep(p, &wait_lock);  //DOC: wait-sleep    }  } | 
