diff options
author | Robert Morris <[email protected]> | 2019-07-25 06:30:49 -0400 |
---|---|---|
committer | Robert Morris <[email protected]> | 2019-07-25 06:30:49 -0400 |
commit | 4e62de64cd3b8b67bdb2c3d8edab1ca353427a84 (patch) | |
tree | b3f2c9b723486d2855574c330d4391c647093e33 /kernel/proc.c | |
parent | b19adf79f9ef5174cd0ff51b703f2ec0d9ad3cde (diff) | |
download | xv6-labs-4e62de64cd3b8b67bdb2c3d8edab1ca353427a84.tar.gz xv6-labs-4e62de64cd3b8b67bdb2c3d8edab1ca353427a84.tar.bz2 xv6-labs-4e62de64cd3b8b67bdb2c3d8edab1ca353427a84.zip |
fix an exit/exit deadlock -> one more locking protocol violation
increase timer rate from 1/second to 10/second
Diffstat (limited to 'kernel/proc.c')
-rw-r--r-- | kernel/proc.c | 24 |
1 files changed, 14 insertions, 10 deletions
diff --git a/kernel/proc.c b/kernel/proc.c index 5136766..48b006f 100644 --- a/kernel/proc.c +++ b/kernel/proc.c @@ -294,17 +294,21 @@ reparent(struct proc *p, struct proc *parent) { int child_of_init = (p->parent == initproc); for(pp = proc; pp < &proc[NPROC]; pp++){ - if (pp != p && pp != parent) { + // this code uses pp->parent without holding pp->lock. + // acquiring the lock first could cause a deadlock + // if pp or a child of pp were also in exit() + // and about to try to lock p. + if(pp->parent == p){ + // pp->parent can't change between the check and the acquire() + // because only the parent changes it, and we're the parent. acquire(&pp->lock); - if(pp->parent == p){ - pp->parent = initproc; - if(pp->state == ZOMBIE) { - if(!child_of_init) - acquire(&initproc->lock); - wakeup1(initproc); - if(!child_of_init) - release(&initproc->lock); - } + pp->parent = initproc; + if(pp->state == ZOMBIE) { + if(!child_of_init) + acquire(&initproc->lock); + wakeup1(initproc); + if(!child_of_init) + release(&initproc->lock); } release(&pp->lock); } |