This commit is contained in:
Robert Morris 2019-07-07 14:57:16 -04:00
parent c4f6a241cd
commit 4ce3a5fa21

View file

@ -76,8 +76,9 @@ allocpid() {
//PAGEBREAK: 32 //PAGEBREAK: 32
// Look in the process table for an UNUSED proc. // Look in the process table for an UNUSED proc.
// If found, change state to EMBRYO and initialize // If found, change state to EMBRYO, initialize
// state required to run in the kernel. // state required to run in the kernel,
// and return with p->lock held.
// Otherwise return 0. // Otherwise return 0.
static struct proc* static struct proc*
allocproc(void) allocproc(void)
@ -124,7 +125,7 @@ found:
// free a proc structure and the data hanging from it, // free a proc structure and the data hanging from it,
// including user pages. // including user pages.
// the proc lock must be held. // p->lock must be held.
static void static void
freeproc(struct proc *p) freeproc(struct proc *p)
{ {
@ -259,6 +260,7 @@ fork(void)
// Copy user memory from parent to child. // Copy user memory from parent to child.
if(uvmcopy(p->pagetable, np->pagetable, p->sz) < 0){ if(uvmcopy(p->pagetable, np->pagetable, p->sz) < 0){
freeproc(np); freeproc(np);
release(&np->lock);
return -1; return -1;
} }
np->sz = p->sz; np->sz = p->sz;
@ -290,9 +292,10 @@ fork(void)
// Pass p's abandoned children to init. p and p's parent // Pass p's abandoned children to init. p and p's parent
// are locked. // are locked.
void reparent(struct proc *p, struct proc *parent) { void
reparent(struct proc *p, struct proc *parent) {
struct proc *pp; struct proc *pp;
int init_is_my_parent = (p->parent == initproc); int child_of_init = (p->parent == initproc);
for(pp = ptable.proc; pp < &ptable.proc[NPROC]; pp++){ for(pp = ptable.proc; pp < &ptable.proc[NPROC]; pp++){
if (pp != p && pp != parent) { if (pp != p && pp != parent) {
@ -300,10 +303,10 @@ void reparent(struct proc *p, struct proc *parent) {
if(pp->parent == p){ if(pp->parent == p){
pp->parent = initproc; pp->parent = initproc;
if(pp->state == ZOMBIE) { if(pp->state == ZOMBIE) {
if(!init_is_my_parent) if(!child_of_init)
acquire(&initproc->lock); acquire(&initproc->lock);
wakeup1(initproc); wakeup1(initproc);
if(!init_is_my_parent) if(!child_of_init)
release(&initproc->lock); release(&initproc->lock);
} }
} }
@ -431,10 +434,8 @@ scheduler(void)
// Process is done running for now. // Process is done running for now.
// It should have changed its p->state before coming back. // It should have changed its p->state before coming back.
c->proc = 0; c->proc = 0;
release(&p->lock);
} else {
release(&p->lock);
} }
release(&p->lock);
} }
} }
} }