diff --git a/Notes b/Notes
index 8fab37d..b5f4035 100644
--- a/Notes
+++ b/Notes
@@ -114,26 +114,15 @@ wakeup needs proc_table_lock
   so we need recursive locks?
   or you must hold the lock to call wakeup?
 
-if locks contain proc *, they can't be used at interrupt time
-  only proc_table_lock will be used at interrupt time?
-  maybe it doesn't matter if we use curproc?
-
 in general, the table locks protect both free-ness and
   public variables of table elements
   in many cases you can use table elements w/o a lock
   e.g. if you are the process, or you are using an fd
 
-why can't i get a lock in console code?
-  always triple fault
-  because release turns on interrupts!
-  a bad idea very early in main()
-  but mp_init() calls cprintf
-
 lock code shouldn't call cprintf...
-ide_init doesn't work now?
-and IOAPIC: read from unsupported address
-  when running pre-empt user test
-  so maybe something wrong with clock interrupts
-  no! if one cpu holds lock w/ curproc0=,
-    then another cpu can take it, it looks like
-    a recursive acquire()
+
+nasty hack to allow locks before first process,
+  and to allow them in interrupts when curproc may be zero
+
+race between release and sleep in sys_wait()
+race between sys_exit waking up parent and setting state=ZOMBIE
diff --git a/proc.c b/proc.c
index 53469a1..0e35540 100644
--- a/proc.c
+++ b/proc.c
@@ -181,7 +181,9 @@ swtch(int newstate)
 {
   struct proc *p = curproc[cpu()];
   if(p == 0)
-    panic("swtch");
+    panic("swtch no proc");
+  if(p->locks != 0)
+    panic("swtch w/ locks");
   p->newstate = newstate; // basically an argument to scheduler()
   if(setjmp(&p->jmpbuf) == 0)
     longjmp(&cpus[cpu()].jmpbuf);
@@ -203,9 +205,11 @@ wakeup(void *chan)
   struct proc *p;
 
   acquire(&proc_table_lock);
-  for(p = proc; p < &proc[NPROC]; p++)
-    if(p->state == WAITING && p->chan == chan)
+  for(p = proc; p < &proc[NPROC]; p++){
+    if(p->state == WAITING && p->chan == chan){
       p->state = RUNNABLE;
+    }
+  }
   release(&proc_table_lock);
 }
 
@@ -225,7 +229,7 @@ proc_exit()
   struct proc *cp = curproc[cpu()];
   int fd;
 
-  cprintf("exit %x\n", cp);
+  cprintf("exit %x pid %d ppid %d\n", cp, cp->pid, cp->ppid);
 
   for(fd = 0; fd < NOFILE; fd++){
     if(cp->fds[fd]){
@@ -246,7 +250,7 @@ proc_exit()
     if(p->ppid == cp->pid)
       p->pid = 1;
 
-  acquire(&proc_table_lock);
+  release(&proc_table_lock);
 
   // switch into scheduler
   swtch(ZOMBIE);
@@ -265,10 +269,8 @@ cli(void)
 void
 sti(void)
 {
-  if(cpus[cpu()].clis < 1){
-    cprintf("cpu %d clis %d\n", cpu(), cpus[cpu()].clis);
+  if(cpus[cpu()].clis < 1)
     panic("sti");
-  }
   cpus[cpu()].clis -= 1;
   if(cpus[cpu()].clis < 1)
     __asm __volatile("sti");
diff --git a/proc.h b/proc.h
index 4c5807b..e13df41 100644
--- a/proc.h
+++ b/proc.h
@@ -45,6 +45,7 @@ struct proc{
   int ppid;
   void *chan; // sleep
   int killed;
+  int locks; // # of locks currently held
   struct fd *fds[NOFILE];
 
   struct Taskstate ts;  // only to give cpu address of kernel stack
diff --git a/spinlock.c b/spinlock.c
index bd6bff5..507e74b 100644
--- a/spinlock.c
+++ b/spinlock.c
@@ -17,10 +17,11 @@ int getcallerpc(void *v) {
 void
 acquire(struct spinlock * lock)
 {
+  struct proc *cp = curproc[cpu()];
   unsigned who;
 
-  if(curproc[cpu()])
-    who = (unsigned) curproc[cpu()];
+  if(cp)
+    who = (unsigned) cp;
   else
     who = cpu() + 1;
 
@@ -38,16 +39,20 @@ acquire(struct spinlock * lock)
     lock->who = who;
   }
 
+  if(cp)
+    cp->locks += 1;
+
   if(DEBUG) cprintf("cpu%d: acquired at %x\n", cpu(), getcallerpc(&lock));
 }
 
 void
 release(struct spinlock * lock)
 {
+  struct proc *cp = curproc[cpu()];
   unsigned who;
 
-  if(curproc[cpu()])
-    who = (unsigned) curproc[cpu()];
+  if(cp)
+    who = (unsigned) cp;
   else
     who = cpu() + 1;
 
@@ -57,6 +62,8 @@ release(struct spinlock * lock)
     panic("release");
 
   lock->count -= 1;
+  if(cp)
+    cp->locks -= 1;
   if(lock->count < 1){
     lock->who = 0;
     cmpxchg(1, 0, &lock->locked);
diff --git a/trap.c b/trap.c
index 862225b..6f5409b 100644
--- a/trap.c
+++ b/trap.c
@@ -62,6 +62,9 @@ trap(struct Trapframe *tf)
     struct proc *cp = curproc[cpu()];
     lapic_timerintr();
     if(cp){
+      if(cpus[cpu()].clis != 0)
+        panic("trap clis > 0");
+      cpus[cpu()].clis += 1;
       sti();
       if(cp->killed)
         proc_exit();
@@ -69,6 +72,7 @@ trap(struct Trapframe *tf)
     }
     return;
   }
+
   if(v == (IRQ_OFFSET + IRQ_IDE)){
     ide_intr();
     return;
diff --git a/usertests.c b/usertests.c
index fa1b210..2f688ca 100644
--- a/usertests.c
+++ b/usertests.c
@@ -93,8 +93,8 @@ preempt()
 main()
 {
   puts("usertests starting\n");
-  //pipe1();
-  preempt();
+  pipe1();
+  //preempt();
 
   while(1)
     ;