diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/proc.c | 52 | 
1 files changed, 25 insertions, 27 deletions
| diff --git a/kernel/proc.c b/kernel/proc.c index 7265174..9202b61 100644 --- a/kernel/proc.c +++ b/kernel/proc.c @@ -288,6 +288,22 @@ fork(void)    return pid;  } +void reparent(struct proc *p) { +  struct proc *pp; + +  // Pass p's abandoned children to init. +  for(pp = ptable.proc; pp < &ptable.proc[NPROC]; pp++){ +    acquire(&pp->lock); +    if(pp->parent == p){ +      pp->parent = initproc; +      if(pp->state == ZOMBIE) { +          wakeup1(initproc); +      } +    } +    release(&pp->lock); +  } +} +  // Exit the current process.  Does not return.  // An exited process remains in the zombie state  // until its parent calls wait(). @@ -315,37 +331,22 @@ exit(void)    iput(cwd);    end_op(); +  reparent(p); +   +  acquire(&p->parent->lock); +        acquire(&p->lock);    p->cwd = 0; - -  // Jump into the scheduler, never to return.    p->state = ZOMBIE; -  sched(); -  panic("zombie exit"); -} -void reparent(struct proc *p) { -  struct proc *pp; -  struct proc *parent = p->parent; +  release(&p->parent->lock); -  acquire(&parent->lock); -      // Parent might be sleeping in wait(). -  wakeup1(parent); - -  // Pass p's abandoned children to init. -  for(pp = ptable.proc; pp < &ptable.proc[NPROC]; pp++){ -    if(pp->parent == p){ -      pp->parent = initproc; -      if(pp->state == ZOMBIE) { -          acquire(&initproc->lock); -          wakeup1(initproc); -          acquire(&initproc->lock); -      } -    } -  } +  wakeup1(p->parent); -  release(&parent->lock); +  // Jump into the scheduler, never to return. +  sched(); +  panic("zombie exit");  }  // Wait for a child process to exit and return its pid. @@ -421,9 +422,6 @@ scheduler(void)          // It should have changed its p->state before coming back.          c->proc = 0;          release(&p->lock); -        if(p->state == ZOMBIE) { -          reparent(p); -        }        } else {          release(&p->lock);        } | 
