From 4e62de64cd3b8b67bdb2c3d8edab1ca353427a84 Mon Sep 17 00:00:00 2001 From: Robert Morris Date: Thu, 25 Jul 2019 06:30:49 -0400 Subject: fix an exit/exit deadlock -> one more locking protocol violation increase timer rate from 1/second to 10/second --- kernel/proc.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'kernel/proc.c') 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); } -- cgit v1.2.3