change allocproc() back to acquiring the ptable.lock.

fix bugs where caller incorrectly released lock on error return path.
This commit is contained in:
Robert Morris 2016-09-15 12:12:05 -04:00
parent 469aa8b9b3
commit aeaa308943

20
proc.c
View file

@ -31,22 +31,27 @@ pinit(void)
// If found, change state to EMBRYO and initialize // If found, change state to EMBRYO and initialize
// state required to run in the kernel. // state required to run in the kernel.
// Otherwise return 0. // Otherwise return 0.
// Must hold ptable.lock.
static struct proc* static struct proc*
allocproc(void) allocproc(void)
{ {
struct proc *p; struct proc *p;
char *sp; char *sp;
acquire(&ptable.lock);
for(p = ptable.proc; p < &ptable.proc[NPROC]; p++) for(p = ptable.proc; p < &ptable.proc[NPROC]; p++)
if(p->state == UNUSED) if(p->state == UNUSED)
goto found; goto found;
release(&ptable.lock);
return 0; return 0;
found: found:
p->state = EMBRYO; p->state = EMBRYO;
p->pid = nextpid++; p->pid = nextpid++;
release(&ptable.lock);
// Allocate kernel stack. // Allocate kernel stack.
if((p->kstack = kalloc()) == 0){ if((p->kstack = kalloc()) == 0){
p->state = UNUSED; p->state = UNUSED;
@ -79,14 +84,7 @@ userinit(void)
struct proc *p; struct proc *p;
extern char _binary_initcode_start[], _binary_initcode_size[]; extern char _binary_initcode_start[], _binary_initcode_size[];
acquire(&ptable.lock);
p = allocproc(); p = allocproc();
// release the lock in case namei() sleeps.
// the lock isn't needed because no other
// thread will look at an EMBRYO proc.
release(&ptable.lock);
initproc = p; initproc = p;
if((p->pgdir = setupkvm()) == 0) if((p->pgdir = setupkvm()) == 0)
@ -145,22 +143,16 @@ fork(void)
int i, pid; int i, pid;
struct proc *np; struct proc *np;
acquire(&ptable.lock);
// Allocate process. // Allocate process.
if((np = allocproc()) == 0){ if((np = allocproc()) == 0){
release(&ptable.lock);
return -1; return -1;
} }
release(&ptable.lock);
// Copy process state from p. // Copy process state from p.
if((np->pgdir = copyuvm(proc->pgdir, proc->sz)) == 0){ if((np->pgdir = copyuvm(proc->pgdir, proc->sz)) == 0){
kfree(np->kstack); kfree(np->kstack);
np->kstack = 0; np->kstack = 0;
np->state = UNUSED; np->state = UNUSED;
release(&ptable.lock);
return -1; return -1;
} }
np->sz = proc->sz; np->sz = proc->sz;