From aeaa308943a14acfaab00f0d9af8424d21a991ae Mon Sep 17 00:00:00 2001
From: Robert Morris <rtm@csail.mit.edu>
Date: Thu, 15 Sep 2016 12:12:05 -0400
Subject: change allocproc() back to acquiring the ptable.lock. fix bugs where
 caller incorrectly released lock on error return path.

---
 proc.c | 20 ++++++--------------
 1 file changed, 6 insertions(+), 14 deletions(-)

diff --git a/proc.c b/proc.c
index eee79af..7d03ad7 100644
--- a/proc.c
+++ b/proc.c
@@ -31,22 +31,27 @@ pinit(void)
 // If found, change state to EMBRYO and initialize
 // state required to run in the kernel.
 // Otherwise return 0.
-// Must hold ptable.lock.
 static struct proc*
 allocproc(void)
 {
   struct proc *p;
   char *sp;
 
+  acquire(&ptable.lock);
+
   for(p = ptable.proc; p < &ptable.proc[NPROC]; p++)
     if(p->state == UNUSED)
       goto found;
+
+  release(&ptable.lock);
   return 0;
 
 found:
   p->state = EMBRYO;
   p->pid = nextpid++;
 
+  release(&ptable.lock);
+
   // Allocate kernel stack.
   if((p->kstack = kalloc()) == 0){
     p->state = UNUSED;
@@ -79,14 +84,7 @@ userinit(void)
   struct proc *p;
   extern char _binary_initcode_start[], _binary_initcode_size[];
 
-  acquire(&ptable.lock);
-
   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;
   if((p->pgdir = setupkvm()) == 0)
@@ -145,22 +143,16 @@ fork(void)
   int i, pid;
   struct proc *np;
 
-  acquire(&ptable.lock);
-
   // Allocate process.
   if((np = allocproc()) == 0){
-    release(&ptable.lock);
     return -1;
   }
 
-  release(&ptable.lock);
-
   // Copy process state from p.
   if((np->pgdir = copyuvm(proc->pgdir, proc->sz)) == 0){
     kfree(np->kstack);
     np->kstack = 0;
     np->state = UNUSED;
-    release(&ptable.lock);
     return -1;
   }
   np->sz = proc->sz;
-- 
cgit v1.2.3